home *** CD-ROM | disk | FTP | other *** search
/ Night Owl 6 / Night Owl's Shareware - PDSI-006 - Night Owl Corp (1990).iso / 001a / mskrmsrc.zip / MSYIBM.ASM < prev    next >
Assembly Source File  |  1991-10-24  |  144KB  |  4,607 lines

  1.     NAME msyibm
  2. ; File MSYIBM.ASM
  3.     include mssdef.h
  4. ;       Copyright (C) 1982,1991, Trustees of Columbia University in the
  5. ;       City of New York.  Permission is granted to any individual or
  6. ;       institution to use, copy, or redistribute this software as long as
  7. ;       it is not sold for profit and this copyright notice is retained.
  8. ; edit history:
  9. ; 6 Sept 1991 version 3.11
  10. ; Last edit 6 Sept 1991
  11. ; 23 Dec 1990 Add Bert Tyler's (NIH) IBM XGA 132 column code.
  12. ; 9 May 1989 Add Bert Tyler's (NIH) new screen rollback routines.
  13. ; 21 Jan 1989 be more tolerate of propriatary video modes above 18 when
  14. ;  determining screen segment, Tnx to Terry Kennedy. Add check for IBM
  15. ;  85xx monitors on Video 7 boards, no 132 columns if it is the monitor.
  16. ;  Retain 43 rows on Video 7 boards.
  17. ; 30 Nov 1988 Add SET TERM CLEAR screen clearing support.
  18. ; 28 Nov 1988 Accomodate Tseng Labs UltraPAK mono/Herc board w/132 cols.
  19. ;  132 column mode is 18h. Requires Tseng's BIGSCR.COM (use BIGSCR /R:25
  20. ;  to enable 132x25 feature). Thanks to Tseng Labs for technical support.
  21. ; 21 Nov 1988 Version 2.32
  22. ; 14 Nov 1988 Write a space during lclini to obtain default screen colors.
  23. ; 12 Nov 1988 Add procs vtrmac and vtsmac to allow exit from Connect mode and
  24. ;  invokation of macros TERMINALR and TERMINALS by reception of escape seqs
  25. ;  in file mszibm.asm or by keyboard verbs.
  26. ; 7 Oct 1988 Reverse left/right arrow key codes when writing right to left.
  27. ; 24 Sept 1988 Make output to printer be buffered and flow controlled.
  28. ; 1 July 1988 Version 2.31
  29. ; 19 June 1988 Add Everex EVGA support, from Terry Kennedy.
  30. ; 10 June 1988 Add oldsp and procedure endcon to exit Connect mode if output
  31. ;  fails, mostly for networking (but we don't know that here).
  32. ; 23 May 1988 Add Everex EV-659 ega board test from Alex Zliu. Fixed incorrect
  33. ;  screen width assumption at startup.
  34. ; 29 March 1988 Include flag ttyact to group string bytes into one net packet,
  35. ;  thanks to Paul Fox of AT&T.
  36. ; 23 March 1988 Add "fairness" word to let serial port deliver max chars
  37. ;  between kbd reads, for connect mode only. [jrd]
  38. ; 10 Feb 1988 Revise getcirc and vtscrX routines to do proper scrolling with
  39. ;  MS Window 1.0x/2.0x [jrd].
  40. ; 9 Feb 1988 Mode line again. Make flags.modflg 0 for off, 1 for on and owned
  41. ;  by Kermit, and 2 for on and owned by remote host (toggling suppressed).
  42. ; 25 Jan 1988 Add global byte SCROLL, set in msz, to control emulator screen
  43. ;  scrolling for higher speeds. [jrd]
  44. ; 5 Jan 1988 Restore cursor codes broken by Tek code additions. [jrd]
  45. ; 1 Jan 1988 version 2.30
  46.  
  47.     public    term, lclyini                ; entry points
  48.     public    prtbout, prtnout, csrtype, scrseg
  49.     public    atsclr, vtscru, vtscrd, trnmod, vclick, vtbell
  50.     public    chgdsp, vtroll, crt_lins, crt_cols, tv_mode, vtclear
  51.             ; action verb procedures for keyboard translator
  52.     public    uparrw, dnarrw, rtarr, lfarr, pf1, pf2, pf3, pf4
  53.     public    kp0, kp1, kp2, kp3, kp4, kp5, kp6, kp7, kp8, kp9
  54.     public    kpminus, kpcoma, kpenter, kpdot, chrout, cstatus, cquit
  55.     public    cquery, dmpscn,    vtans52, vtinit, dnwpg, upwpg, endwnd, homwnd
  56.     public    upone, dnone, trnprs, dumpscr, modlin, snull
  57.     public    klogon, klogof, cdos, chang, khold, vtrmac, vtsmac, product
  58.     public    decf6,decf7,decf8,decf9,decf10,decf11,decf12,decf13,decf14
  59.     public    dechelp,decdo,decf17,decf18,decf19,decf20, udkclear
  60.     public    decfind, decinsert, decremove, decselect, decprev
  61.     public    decnext, setudk, extmacro, vtmacname, vtmaclen
  62.  
  63.     public    vtemu, crt_mode, scbattr, refresh, low_rgt    ; data
  64.     public    setchtab
  65.         public  savescr, restscr            ; code
  66.     public    setpos, getpos, getatch, setatch, putchar, yflags
  67.     public    getbold, setbold, clrbold, getblink, setblink, clrblink
  68.     public    getunder, setunder, clrunder, revideo, revscn, setcolor
  69.     public    setrev, clrrev, insdecom
  70.     public    vts, vtstat, termtb            ; terminal emulation
  71.  
  72. ; some definitions
  73. ; hardware
  74. crt_status equ    3dah            ; CGA crt status port
  75. disp_enb equ    8            ; CGA display enable bit
  76. crtmset    equ    3D8H            ; CGA CRT mode set port
  77. screen    equ    10h            ; Bios screen interrupt
  78.  
  79. modfrm    struc                ; format of mode (status) line
  80.     db    'Esc-chr: '        ; do not write in last column
  81. m_echr    db    2 dup (' ')
  82.     db    '  help: '
  83. m_hlp    db    2 dup (' ')
  84.     db    '?  port:'
  85. m_prt    db    1 dup (' ')
  86.     db    ' speed:'
  87. m_baud    db    6 dup (' ')
  88.     db    'parity:'
  89. m_par    db    4 dup (' ')
  90.     db    ' echo:'
  91. m_echo    db    3 dup (' ')
  92. m_term    db    13 dup (' ')        ; 13 bytes for term type
  93. m_prn    db    3 dup (' ')        ; show PRN when printer is on
  94.     db    '$'            ; terminator
  95. modfrm    ends
  96.  
  97. ; structure for status information table sttab.
  98. stent    struc
  99. sttyp    dw    ?        ; type (actually routine to call)
  100. msg    dw    ?        ; message to print
  101. val2    dw    ?        ; needed value: another message, or tbl addr
  102. tstcel    dw    ?        ; address of cell to test, in data segment
  103. basval    dw    0        ; base value, if non-zero
  104. stent    ends
  105.  
  106.  
  107. data    segment
  108.     extrn    flags:byte, mar_top:byte, mar_bot:byte, portval:word
  109.     extrn    filtst:byte, dmpname:byte, kbdflg:byte, rxtable:byte
  110.     extrn    anspflg:byte, tekflg:byte, scroll:byte, ttyact:byte
  111.     extrn    holdscr:byte, taklev:byte, takadr:word, mcctab:byte
  112.     extrn    video_state:byte, trans:byte, npages:word, comand:byte
  113.     extrn    denyflg:word, tekgraf:byte, rdbuf:byte, dupflg:byte
  114.     extrn    chcontrol:byte, kbcodes:byte, repflg:byte, tekcursor:byte
  115.     extrn    decbuf:byte, param:word, nparam:word, prnhand:word
  116.     extrn    upss:byte, comptab:byte
  117.  
  118. ; stuff for screen routines
  119. yflags    db    0            ; status flags
  120. prtscr    equ    1            ; print screen pressed
  121. inited    equ    08h            ; been here before
  122. vtinited db    0            ; flag for emulator having been inited
  123. vtclear    db    0            ; nonzero to redo emulator screen
  124. cursor    dw    0
  125. parmsk    db    0            ; 8/7 bit parity mask, for reception
  126. argadr    dw    0            ; address of arg blk
  127. skip    dw    0
  128.  
  129. vid7id    db    'VEGA BIOS Code, '    ; Video 7 Vega version string subset
  130. vid7len    equ    $-vid7id        ; length of string
  131. vid7id2    db    'Video Seven BIOS Code, ' ; Video 7 VGA board
  132. vid7len2 equ    $-vid7id2
  133. atiwid    db    'ATI EGA Wonder Bios,'    ; ATI EGA wonder version string subset
  134. atilen    equ    $-atiwid        ; length of string, inc terminator
  135. atiwid2    db    '761295520'        ; ATI signature #2
  136. atilen2    equ    $-atiwid2
  137. tsngid    db    'Tseng'            ; Tseng Labs EVA (& Orchid Designer)
  138. tsnglen    equ    $-tsngid
  139. stbvid    db    'TVGA'            ; STB VGA/EM (also Tseng TVGA)
  140. stbvlen    equ    $-stbvid
  141. stavid    db    '4000'            ; STB VGA/EM Plus (Tesng 4000)
  142. stavlen equ    $-stavid
  143. evrxid  db      'Everex'                ; Everex Micro Enhancer Deluxe EGA
  144. evrxlen equ     $-evrxid
  145. evgid    db    'VGA EV673'        ; Everex EVGA EV-673
  146. evglen    equ    $-evgid
  147. evvid    db    'EV-678'        ; Everex Viewpoint EV-678
  148. evvlen    equ    $-evvid
  149. attvdc6    db    '003116'        ; AT&T video board, at c000:35h
  150. attvdlen equ    $-attvdc6
  151. attvdc7    db    'C02000'        ; AT&T video board, at e000:10h
  152. pmega1    db    '28190-A1001'        ; Paradise AutoSwitch EGA Mono String1
  153. pmegal1 equ    $-pmega1        
  154. p30id    db    'VGA'            ; VGA Plus, Plus 16, Professional
  155. p30ln    equ    $-p30id            ;  and VGA1024 by Paradise
  156. cols80    db    'COLS80.BAT',0        ; to 80 column mode batch file
  157. cols132    db    'COLS132.BAT',0        ; to 132 column mode batch file
  158. xga_reg_base dw    -1            ; PS/2 MCA I/O register base
  159. ega_mode db    0            ; non-zero if IBM EGA is in use
  160. tvhere    equ    0feh            ; Topview active query
  161. tvsynch    equ    0ffh            ; Topview resynch request
  162. tv_segs    dw    0            ; Topview virtual screen, segment
  163. tv_sego    dw    0            ; and offset
  164. tv_mode    db    0            ; flag, 0 = no Topview or DESQview
  165. savadr    dw    2 dup (0)        ; offset then segment of saved screen
  166. savflg    dw    0            ; low_rgt at time of screen save
  167. att_low_mask    equ    06H        ; Various attribute-related equates
  168. att_underline    equ    01H
  169. att_intensity    equ    08H
  170. att_blink    equ    80H
  171. att_normal    equ    07h
  172.  
  173. ; The following are used to turn the display back on (after scrolling etc.)
  174. msets    db    2CH,28H,2DH,29H,2AH,2EH,1EH,29H
  175.  
  176.  
  177. vtemu    emulst    <>            ; emulator flags
  178. trmtyp    db    0            ; most recent terminal type
  179. mtty    db    '  TTY   '        ; no terminal type (mode line)
  180. belltype db    0            ; 0 = aural bell, 1 = visual
  181. fairness dw    0
  182. fairprn    dw    0
  183. lincur    dw    ?            ; cursor type save area
  184. scbattr db    ?            ; screen background attribute
  185. dosattr    db    ?            ; screen attributes at init time
  186. userbold db    0            ; screen bold attribute at start up
  187. dos_cols db    0            ; screen width (crt_cols) at DOS
  188. savattr    db    ?            ; current emulator attributes
  189. oldsp    dw    0            ; offset to longjmp to for i/o failure
  190. ten    db    10            ; byte constant for key defines
  191. temp    dw    0            ; scratch storage
  192. captrtn    dw    0            ; routine to call for captured output
  193. dmphand    dw    -1            ; screen dump file handle
  194. dumplen    equ    132
  195. dumpbuf    db    dumplen dup (0), cr, lf    ; 134 byte dump work buffer
  196. dumpsep    db    FF,cr,lf        ; screen image separators
  197. dmperr    db    ' Cannot open file to save screen to disk $'
  198. memerr    db    cr,lf,'Not enough memory for terminal emulator$'
  199. crlf    db    cr,lf,'$'
  200. flowon    db    0            ; flow control chars xon
  201. flowoff    db    0            ;  and xoff (or both null if none)
  202. pntmsg    db    'Printer not ready, printing request skipped$'
  203. upsshlp    db    cr,lf,'User Preferred Supplemental Set: DEC-MCS or Latin-1$'
  204.  
  205. ; some static data for mode line
  206. modmaster modfrm <>            ; master template
  207. modbuf    modfrm    <>            ; mode line buffer
  208. unkbaud    db    'unkwn '        ; must be 6 chars
  209. baudn    db    ' 45.5 ',' 50   ',' 75   ',' 110  ','134.5 ',' 150  ',' 300  '
  210.     db    ' 600  ',' 1200 ',' 1800 ',' 2000 ',' 2400 ',' 4800 ',' 9600 '
  211.     db    '19200 ','38400 ','57.6K ','115 K ','75/12 '
  212. baudnsiz  equ    19            ; # of baud rates known (tbl size / 4)
  213. repmsg    db    'REPLAY'        ; REPLAY message for speed field
  214. repmsgl    equ    $-repmsg
  215. parnams    db    'even','mark','none','odd ','spc '
  216. lclmsg    db    'loc'
  217. remmsg    db    'rem'
  218. portno    db    0
  219.  
  220. ; storage for multi-window stuff
  221. swidth    equ    80            ; max screen width
  222. slen    equ    24            ; and length of text
  223. crt_norm db    3            ; video mode for normal screen
  224. crt_mode db    3            ; video mode (typ 3, must be text)
  225.                     ; keep crt_cols & crt_lins in order
  226. crt_cols db    80            ; number of screen columns (typ 80)
  227. crt_lins db    24            ; number of screen rows - 1 (typ 24)
  228. low_rgt    dw    174fh            ; lower right corner of text window
  229.                     ; high = row address (typ 23)
  230.                     ; low = column address (typ 79)
  231. inipara    dw    0            ; initial paragraphs of scroll memory
  232. refresh    db    0            ; screen refresh (0=wait for retrace)
  233. vtroll    db    0            ; auto roll back allowed (0 = no)
  234.  
  235. vtrname    db    'TERMINALR'        ; a macro name, must be Upper Case
  236. vtrlen    equ    $-vtrname
  237. vtsname    db    'TERMINALS'        ; a macro name, must be Upper Case
  238. vtslen    equ    $-vtsname
  239. prodname db    'PRODUCT'
  240. vtplen    equ    $-prodname
  241. vtmacname dw    vtrname            ; pointer to selected macro name
  242. vtmaclen dw    vtrlen
  243. udkseg    dw    18 dup (0)        ; segment of user definable key defs
  244.     even                ; screen rollback material
  245. iniseg    dw    ?            ; (BDT) initial seg of scroll memory
  246. ppl    dw    0            ; (BDT) paragraphs per line
  247. lcnt    dw    0            ; (BDT) number of "filled" buffer lines
  248. linef    dw    0            ; (BDT) "first" filled line is here
  249. linec    dw    0            ; (BDT) "current" screen line number
  250. linee    dw    0            ; (BDT) total # of lines in the buffer
  251. lmax    dw    0            ; (BDT) max lines in buff (less 1 scrn)
  252. lxtra    dw    0            ; (BDT) "extra" lines rqd for screen
  253.  
  254. setchtab db    6            ; Set File Character-Set table
  255.     mkeyw    'CP437',437        ; hardware default Code Page
  256.     mkeyw    'CP850',850        ; Multilingual CP
  257.     mkeyw    'CP860',860        ; Portuguese CP
  258.     mkeyw    'CP863',863        ; French Canadian CP
  259.     mkeyw    'CP865',865        ; Norwegian CP
  260.     mkeyw    'CP866',866        ; Latin5/Cryillic CP
  261. ;;    mkeyw    'User-defined',1    ; User loadable table
  262.  
  263.  
  264.                     ; begin Terminal emulator data set
  265. termtb    db    tttypes            ; entries for Status, not Set
  266.     mkeyw    'VT320',ttvt320
  267.     mkeyw    'VT220',ttvt220
  268.     mkeyw    'VT102',ttvt102
  269.     mkeyw    'VT100',ttvt100
  270.     mkeyw    'VT52',ttvt52
  271.     mkeyw    'Honeywell VIP7809',tthoney
  272.     mkeyw    'Heath-19',ttheath
  273.     mkeyw    'Tek4010',tttek
  274.     mkeyw    'none',ttgenrc
  275.  
  276.  
  277. vttbl    db    32            ; number of entries
  278.     mkeyw    'Arrow-keys',arkval
  279.     mkeyw    'Bell',8800h        ; note 8800 flag for decoding
  280.     mkeyw    'Bytesize',8900h    ; syn for set display 7/8
  281.     mkeyw    'Character-set',chaval+8300h
  282.     mkeyw    'Clear-screen',8500h    ; 8500h = marker here
  283.     mkeyw    'Color',8200H        ; screen fore/back colors; 200H=marker
  284.     mkeyw    'Controls',cntlval
  285.     mkeyw    'Cursor-style',curval
  286.     mkeyw    'Direction',dirval
  287.     mkeyw    'Display',8900h        ; syn for set display 7/8
  288.     mkeyw    'Graphics',8600h    ; Tek graphics board, 800h=marker
  289.     mkeyw    'Heath-19',ttheath+8100H; note 8100H flag for decoding here
  290.     mkeyw    'Honeywell',tthoney+8100h
  291.     mkeyw    'Keyclick',keyval
  292.     mkeyw    'Keypad',kpamval
  293.     mkeyw    'Margin-bell',marval
  294.     mkeyw    'None',ttgenrc+8100H
  295.     mkeyw    'Newline',newval
  296.     mkeyw    'Replay',8700h        ; note 8700H flag for file replaying
  297.     mkeyw    'Rollback',8400h    ; note 8400H flag for decoding
  298.     mkeyw    'Screen-background',scrval
  299.     mkeyw    'Tabstops',tabval
  300.     mkeyw    'Tek4010',tttek+8100H
  301.     mkeyw    'Type',81ffH        ; SET TERM TYPE
  302.     mkeyw    'VT320',ttvt320+8100H
  303.     mkeyw    'VT220',ttvt220+8100H
  304.     mkeyw    'VT102',ttvt102+8100H
  305.     mkeyw    'VT100',ttvt100+8100h
  306.     mkeyw    'VT52',ttvt52+8100H
  307.     mkeyw    'UPSS',8A00h        ; note 8A00h flag for UPSS
  308.     mkeyw    'Width',widthval
  309.     mkeyw    'Wrap',wraval
  310.  
  311. ontab    db    2            ; two entries
  312.     mkeyw    'off',0
  313.     mkeyw    'on',1
  314.  
  315. beltab    db    3            ; bell type
  316.     mkeyw    'audible',0
  317.     mkeyw    'visual',1
  318.     mkeyw    'none',2
  319.  
  320. distab    db    2            ; display
  321.     mkeyw    '7-bit',0
  322.     mkeyw    '8-bit',d8bit
  323.  
  324. scrtab    db    2            ; screen attributes
  325.     mkeyw    'normal',0
  326.     mkeyw    'reverse',1
  327.  
  328. dirtab    db    2            ; writing direction
  329.     mkeyw    'left-to-right',0
  330.     mkeyw    'right-to-left',1
  331.  
  332. curtab    db    2            ; cursor attributes
  333.     mkeyw    'block',0
  334.     mkeyw    'underline',1
  335.      
  336. chatab    db    18            ; National Replacement Character sets
  337.     mkeyw    'ASCII',0        ; ASCII is default (0, no NRC)
  338.     mkeyw    'British',1        ; start NRC set (1-12)
  339.     mkeyw    'Dutch',2
  340.     mkeyw    'Finnish',3
  341.     mkeyw    'French',4
  342.     mkeyw    'Fr-Canadian',5
  343.     mkeyw    'German',6
  344.     mkeyw    'Italian',7
  345.     mkeyw    'Norwegian/Danish',8
  346.     mkeyw    'Portuguese',9
  347.     mkeyw    'Spanish',10
  348.     mkeyw    'Swedish',11
  349.     mkeyw    'Swiss',12        ; end of NRC proper
  350.     mkeyw    'Alternate-ROM',13    ; Alternate-ROM character set
  351.     mkeyw    'Transparent',14    ; use native display adapter hardware
  352.     mkeyw    'Latin1',15        ; Latin-1 in GR
  353.     mkeyw    'DEC-MCS',16        ; DEC Supplemental Graphics in GR
  354.     mkeyw    'DEC-Special',18
  355.  
  356. upsstab    db    2
  357.     mkeyw    'DEC-MCS',94        ; DEC Supplemental Graphics
  358.     mkeyw    'Latin1',96        ; Latin-1
  359.  
  360. sidetab    db    4            ; SET TERM CHAR <char set> Gn
  361.     mkeyw    'G0','0'
  362.     mkeyw    'G1','1'
  363.     mkeyw    'G2','2'
  364.     mkeyw    'G3','3'
  365.  
  366. graftab    db    12
  367.     mkeyw    'auto-sensing',0    ; autosensing
  368.     mkeyw    'CGA',1
  369.     mkeyw    'EGA',2
  370.     mkeyw    'VGA',3
  371.     mkeyw    'Hercules',4
  372.     mkeyw    'ATT',5
  373.     mkeyw    'WyseA(1280x800)',6    ; Wyse-700 1280 x 800 mode
  374.     mkeyw    'WyseH(1280x780)',7    ; Wyse-700 1280 x 780 mode
  375.     mkeyw    'WyseT(1024x780)',8    ; Wyse-700 1024 x 780 mode
  376.     mkeyw    'character-writing',101h
  377.     mkeyw    'color',103h
  378.     mkeyw    'cursor',102h
  379.  
  380. gchrtab    db    2            ; set term graphics char-writing
  381.     mkeyw    'opaque',1
  382.     mkeyw    'transparent',0
  383.  
  384. disatab    db    2            ; Tek disable/enable table
  385.     mkeyw    'disable',1
  386.     mkeyw    'enable',0
  387.  
  388. tabtab    db    2            ; label says it all!
  389.     mkeyw    'at',0FFH        ; For setting tab stops
  390.     mkeyw    'Clear',0        ; For clearing tab stops
  391.      
  392. alltab    db    2            ; more tab command decoding
  393.     mkeyw    'all',0
  394.     mkeyw    'at',1
  395.  
  396. cntltab    db    2            ; 8-bit controls
  397.     mkeyw    '7-bit',0
  398.     mkeyw    '8-bit',1
  399.  
  400. kpamtab    db    2            ; keypad, application
  401.     mkeyw    'Numeric',0
  402.     mkeyw    'Application',1
  403.  
  404. arrtab    db    2            ; cursor keys, application
  405.     mkeyw    'Cursor',0
  406.     mkeyw    'Application',1
  407.  
  408.  
  409. widtab    db    2
  410.     mkeyw    '80-columns',0
  411.     mkeyw    '132-columns',1
  412.  
  413. vtable    dw    ontab, ontab, chatab, dirtab ,ontab, ontab, curtab, scrtab
  414.     dw    cntltab, kpamtab, arrtab, widtab, 0
  415. ; which are     newline  wrap   char   direct  key   margin  cursor  screen  
  416. ;        controls key-app arrow-app width
  417.  
  418. vtsflg equ    this word        ; define small digits xxxval
  419. newval    equ    $-vtsflg        ; 0   and mask for bit in byte
  420.     dw    vsnewline        ;  1
  421. wraval    equ    $-vtsflg        ; 2
  422.     dw    vswrap            ;  2
  423. chaval    equ    $-vtsflg        ; 4
  424.     dw    vsnrcm            ;  4
  425. dirval    equ    $-vtsflg        ; 6
  426.     dw    vswdir            ;  8
  427. keyval    equ    $-vtsflg        ; 8
  428.     dw    vskeyclick        ;  10h
  429. marval    equ    $-vtsflg        ; 10
  430.     dw    vsmarginbell        ;  20h
  431. curval    equ    $-vtsflg        ; 12
  432.     dw    vscursor        ;  40h
  433. scrval    equ    $-vtsflg        ; 14
  434.     dw    vsscreen        ;  80h
  435. cntlval    equ    $-vtsflg        ; 16
  436.     dw    vscntl            ;  100h
  437. kpamval    equ    $-vtsflg        ; 18
  438.     dw    deckpam            ;  400h
  439. arkval    equ    $-vtsflg        ; 20
  440.     dw    decckm            ;  200h
  441. widthval equ    $-vtsflg        ; 22
  442.     dw    deccol            ;  1000h
  443. numflgs equ    ($-vtsflg)/2        ;  10
  444. tabval    equ    $-vtsflg        ; 24
  445.     dw    0
  446. vtrtns    dw    numflgs dup (flgset), tabmod ; dispatch table for vtsflg
  447.  
  448. colortb    db    0,4,2,6,1,5,3,7        ; color reversed-bit setting bytes
  449. clrset    db    0            ; Temp for SET Term Tabstops xxx
  450.  
  451. erms41    db    cr,lf,'?More parameters are needed$'
  452. vthlp    db    ' one of the following:',cr,lf
  453.     db '  TYPE of: None, Heath-19, Honeywell VIP7809, VT52,'
  454.     db ' VT100, VT102,',cr,lf,'    VT220, VT320 (default), or Tek4010'
  455.     db    cr,lf
  456.     db '  Newline-mode    Cursor-style        Character-set'
  457.     db     cr,lf
  458.     db '  Keyclick        Margin-bell         Screen-background'
  459.     db    ' (normal, reverse)',cr,lf
  460.     db '  Tabstops        Wrap (long lines)   Color (fore & background)'
  461.     db    cr,lf,'  Arrow-keys  cursor (normal) or application mode'
  462.     db    cr,lf,'  Bell  audible or visual or none'
  463.     db    cr,lf,'  Clear-screen  (clears old startup screen)'
  464.     db    cr,lf,'  Controls 7-bit or 8-bit  (permits VT320 to send'
  465.     db    ' 8-bit control sequences (C1))'
  466.     db    cr,lf,'  Direction Left-to-right or Right-to-left'
  467.     db    ' (screen writing direction)'
  468.     db    cr,lf,'  Display or Bytesize 7-bit or 8-bit'
  469.     db    cr,lf,'  Graphics  (type of display adapter when in Tek4010'
  470.     db    ' mode, and char writing)'
  471.     db    cr,lf,'  Keypad numeric (normal) or application mode'
  472.     db     cr,lf,'  Replay filespec (display a file through the emulator)'
  473.     db    cr,lf,'  Rollback  (undo screen roll back before writing new'
  474.     db    ' chars, default=off)'
  475.     db    cr,lf,'  TEK ENABLE or DISABLE (activation by host command)'
  476.     db    cr,lf,'  Width 80 or 132 columns, if the adapter can do it$'
  477. clrhlp    db    ' one of the following:'
  478.     db    cr,lf,'  AT #s  (to set tabs at column #s)    or'
  479.     db    ' AT start-column:spacing'
  480.     db    cr,lf,'  Clear AT #s (clears individual tabs) or'
  481.     db    ' AT start-column:spacing'
  482.     db    cr,lf,'  Clear ALL  (to clear all tabstops)'
  483. clrhlp2    db    cr,lf,'  Ex: Set term tab at 10, 20, 34        sets tabs'
  484.     db    cr,lf,'  Ex: Set term tab at 1:8        sets tabs at 1, 9,'
  485.     db    cr,lf,'  Ex: Set term tab clear at 9, 17, 65   clears tabs'
  486.     db    cr,lf,'  Ex: Set term tab clear at 1:8  clears tabs at 1, 9,'
  487.     db    ' 17,...$'
  488. tbserr    db    cr,lf,'?Column number is not in range 1 to screen width-1$'
  489. colhlp    db    cr,lf,'  Set Term Color  value, value, value, ...'
  490.     db    cr,lf,'   0 no-snow mode on an IBM CGA and white on black'
  491.     db    cr,lf,'   1 for high intensity foreground'
  492.     db    cr,lf,'  10 for fast CGA screen updating (may cause snow)'
  493.     db    cr,lf,'  Foreground color (30-37) = 30 + sum of colors'
  494.     db    cr,lf,'  Background color (40-47) = 40 + sum of colors'
  495.     db    cr,lf,'    where colors are  1 = red, 2 = green, 4 = blue'
  496.     db    cr,lf,'  Ex: 0, 1, 37, 44   IBM CGA(0), bright(1) white(37)'
  497.     db    ' chars on a blue(44) field'
  498.     db    cr,lf,'  Attributes are applied in order of appearance.$'
  499. colerr    db    cr,lf,'?Value not in range of 0, 1, 10, 30-37, or 40-47$'
  500. vtwrap    db    'Term wrap-lines: $'
  501. vtbellm    db    'Term margin-bell: $'
  502. vtnewln db    'Term newline: $'
  503. vtcur    db    'Term cursor-style: $'
  504. vtcset    db    'Term character-set: $'
  505. vtclik    db    'Term key-click: $'
  506. vtscrn    db    'Term screen-background: $'
  507. colst1    db    'Term color  foregnd:3$'
  508. colst2    db    ' backgnd:4$'
  509. vtgraf    db    'Term graphics: $'
  510. vtrolst    db    'Term rollback: $'
  511. vtdir    db    'Term direction: $'
  512. vtcntst    db    'Term controls: $'
  513. vtkpst    db    'Term keypad: $'
  514. vtarst    db    'Term arrow-keys: $'
  515. vtbset    db    'Term bell: $'
  516. vtgchst    db    'Term graph char: $'
  517. vtwdst    db    'Term width: $'
  518. vtupsst    db    'Term UPSS: $'
  519.  
  520.                         ; terminal emulator
  521. vtstbl    stent    <srchkw,vtcset,chatab,vtemu.vtchset>        ; char set
  522.     stent    <srchkb,vtclik,ontab,vskeyclick,vtemu.vtflgop>    ; keyclick
  523.     stent    <colstat>                    ; colors
  524.     stent    <srchkb,vtwrap,ontab,vswrap,vtemu.vtflgop>    ; line wrap
  525.     stent    <srchkb,vtcntst,cntltab,vscntl,vtemu.vtflgop>    ; controls
  526.     stent    <srchkb,vtbellm,ontab,vsmarginbell,vtemu.vtflgop>;margin bell
  527.     stent    <srchkb,vtcur,curtab,vscursor,vtemu.vtflgop>    ; cursor type
  528.     stent    <srchkw,vtbset,beltab,belltype>            ; bell
  529.     stent    <srchkb,vtdir,dirtab,vswdir,vtemu.vtflgop>    ; write direct
  530.     stent    <srchkb,vtnewln,ontab,vsnewline,vtemu.vtflgop>    ; newline
  531.     stent    <srchkw,vtgraf,graftab,tekgraf>            ; graphics
  532.     stent    <srchkw,vtrolst,ontab,vtroll>            ; rollback
  533.     stent    <srchkw,vtgchst,gchrtab,chcontrol>        ; chr cntrl
  534.     stent    <srchkb,vtarst,arrtab,decckm,vtemu.vtflgop>    ; arrow-keys
  535.     stent    <srchkb,vtscrn,scrtab,vsscreen,vtemu.vtflgop>    ; screen 
  536.     stent    <srchkb,vtkpst,kpamtab,deckpam,vtemu.vtflgop>    ; keypad
  537.     stent    <srchkb,vtwdst,widtab,deccol,vtemu.vtflgop>    ; width
  538.     stent    <srchkw,vtupsst,upsstab,upss>            ; UPSS
  539.     stent    <tabstat>    ; VT320 tab status - needs one whole line
  540.     dw    0        ; end of table
  541.  
  542. endconptr    dw    offset endcon,seg endcon    ; FAR pointer
  543. productptr    dw    offset fproduct,seg fproduct    ; FAR pointer
  544. vtmacroptr    dw    offset vtmacro,seg vtmacro    ; FAR pointer
  545. fxgaman    dw    offset xgaman,seg xgaman        ; FAR pointer
  546. data    ends
  547.                         ; end of Terminal data set
  548.  
  549. code2    segment
  550.     extrn   tekini:far,tekemu:far,tekend:far,tekrint:far ;in msgibm
  551. code2    ends
  552.  
  553. code    segment
  554.     extrn    prtchr:near, outchr:near, sbrk:near, pcwait:near
  555.     extrn    isfile:near                ; in mssfil
  556.     extrn    anstty:near,ansini:near,ansrei:near    ; in mszibm
  557.     extrn    anskbi:near,ansdsl:near            ; in mszibm
  558.     extrn    ans52t:near, vsinit:near        ; in mszibm
  559.     extrn    msuinit:near, keybd:near, kbhold:near    ; in msuibm
  560.     extrn    clrmod:near, putmod:near, cmblnk:near
  561.     extrn    telnet:near, tabset:near, tabclr:near, istabs:near
  562.     extrn    atoi:near, strlen:near, srchkb:near, srchkw:near, pasz:near
  563.     extrn    prompt:near, comnd:near, statc:near, replay:near
  564.     extrn    crun:near, serini:near, spath:near, strcpy:near, tekdmp:near
  565.     extrn    prttab:near, dec2di:near, tekgcptr:near
  566.     extrn    pntchr:near, pntflsh:near
  567. extrn decout:near
  568.     assume    cs:code, ds:data, es:nothing
  569.  
  570.  
  571. fscrmod    proc    FAR
  572.     call    scrmod
  573.     ret
  574. fscrmod    endp
  575. fscrseg    proc    FAR
  576.     call    scrseg
  577.     ret
  578. fscrseg    endp
  579. fscroff    proc    FAR
  580.     call    scroff
  581.     ret
  582. fscroff    endp
  583. fscron    proc    FAR
  584.     call    scron
  585.     ret
  586. fscron    endp
  587. fscrsync proc    FAR
  588.     call    scrsync
  589.     ret
  590. fscrsync endp
  591. fatsclr    proc    FAR
  592.     call    atsclr
  593.     ret
  594. fatsclr    endp
  595. fisfile    proc    FAR
  596.     call    isfile
  597.     ret
  598. fisfile    endp
  599. fgetpos    proc    FAR
  600.     call    getpos
  601.     ret
  602. fgetpos    endp
  603. fsetpos    proc    FAR
  604.     call    setpos
  605.     ret
  606. fsetpos    endp
  607. code    ends
  608.  
  609. code1    segment
  610.     assume    cs:code1
  611.  
  612. ; Save the entire screen in a buffer so we can restore and/or dump it.
  613. ; Saves regular (80x25) screens to memory buffer allocated dynamically from
  614. ; DOS or if insufficient space then to video memory page 1. Save address is
  615. ; savadr+2:savadr (seg:offset). A memory buffer is deallocated and reallocated
  616. ; if it's size needs to change, otherwise it is reused as is.
  617. ; Current crt_cols & crt_lins size info is saved in savflg for restscr. Note,
  618. ; some Environments (TopView/Windows etc) may not permit use of page 1 and we
  619. ; will not save the screen if video page 1 is required under Environments.
  620. fsavescr proc    FAR
  621.     push    es
  622.     push    ds
  623.     push    ax
  624.     push    cx
  625.     push    dx
  626.     push    si
  627.     push    di
  628.     call    fscrmod            ; ascertain video mode and screen
  629.     call    fscrseg            ; get screen segment in ax and es:di
  630.     mov    di,ax            ; save screen seg in di
  631.     mov    ax,word ptr crt_cols    ; text screen lower right (typ 80,24)
  632.     inc    ah            ;  plus status line = number of rows
  633.     mul    ah            ; times rows = characters on screen
  634.     shl    ax,1            ; times two for attributes = page 1
  635.     mov    dx,ax            ; save number of screen bytes in dx
  636.     mov    ax,savadr+2        ; seg of saved memory, if any
  637.     or    ax,ax            ; none?
  638.     jz    savsc1            ; z = yes, none
  639.     cmp    ax,0a000h        ; in video memory?
  640.     jae    savsc1            ; ae = yes
  641.     mov    ax,word ptr crt_cols    ; text screen lower right (typ 80,24)
  642.     cmp    ax,savflg        ; same as saved screen?
  643.     je    savsc4            ; e = yes, no allocation needed
  644.     mov    savflg,ax
  645.     mov    ax,savadr+2        ; get old allocation
  646.     mov    es,ax
  647.     mov    ah,freemem        ; free old memory
  648.     int    dos
  649.     mov    savadr+2,0        ; clear old segment
  650.                     ; allocate and use DOS memory for save
  651. savsc1:    mov    bx,dx            ; bytes to do
  652.     add    bx,15            ; round up
  653.     mov    cl,4
  654.     shr    bx,cl            ; bytes/screen to paragraphs/screen
  655.     mov    ah,alloc        ; allocate memory
  656.     int    dos            ; bx has # free paragraphs
  657.     jc    savsc2            ; c = not enough for it, use video
  658.     mov    savadr+2,ax        ; working seg address for restore
  659.     mov    savadr,0        ; and no offset for memory buffer
  660.     jmp    short savsc4
  661.                     ; use video page 1 as save area
  662. savsc2:    cmp    di,0a000h        ; screen segment is in DOS (Environ)?
  663.     jae    savsc3            ; ae = no
  664.     mov    savadr+2,0        ; then say no seg because no save
  665.     jmp    savsc5            ; exit without saving screen
  666. savsc3:    mov    cx,dx            ; number of screen bytes
  667.     and    cx,000fh        ; get lower four bits for offset part
  668.     mov    savadr,cx        ; save offset in this word
  669.     mov    ax,dx            ; number of screen bytes
  670.     mov    cl,4
  671.     shr    ax,cl            ; compute number of paragraphs 
  672.     add    ax,di            ; add paragraphs, point ax to page 1
  673.     mov    savadr+2,ax        ; and save segment in this word
  674.                     ; save the screen
  675. savsc4:    push    word ptr crt_cols    ; current screen dimensions
  676.     pop    savflg            ; save it for screen restore
  677.     mov    cx,dx            ; number of screen bytes
  678.     shr    cx,1            ; do as words
  679.     push    di            ; preserve di around call
  680.     call    fscroff            ; turn off screen [dt]
  681.     pop    di
  682.     mov    ax,savadr+2        ; destination segment
  683.     mov    es,ax            ; segment of storage area
  684.     push    di            ; screen memory segment from di
  685.     mov    di,savadr        ;  offset of storage
  686.     pop    ds            ; put into ds
  687.     xor    si,si
  688.     cld
  689.     rep    movsw            ; save the screen
  690. savsc5:    pop    di
  691.     pop    si
  692.     pop    dx
  693.     pop    cx
  694.     pop    ax
  695.     pop    ds
  696.     call    fscron            ; turn on screen
  697.     pop    es
  698.     ret
  699. fsavescr endp
  700.  
  701. ; Restore screen from buffer (savadr+2:savadr, with screen size in savflg).
  702. ; Restores all screen lines.
  703. frestscr proc    FAR
  704.     push    es
  705.     push    si
  706.     push    di
  707.      cmp    savadr+2,0        ; saved anything yet?
  708.     jne    restsc1            ; ne = yes
  709.     call    fscrmod            ; get current screen size
  710.     xor    ax,ax
  711.     mov    bx,word ptr crt_cols    ; clear the screen to current colors
  712.     dec    bl            ; count columns from 0
  713.     call    fatsclr
  714.     jmp    short restsc2
  715.  
  716. restsc1:mov    ax,savflg        ; saved low_rgt text screen coord
  717.     inc    ah            ; number of screen rows
  718.     mul    ah            ; columns time lines = # characters
  719.     mov    cx,ax            ; save this in counter cx
  720.     push    cx            ; save count
  721.     call    fscrseg            ; get address of screen in es:di
  722.     call    fscroff            ; turn off screen [dt]
  723.     push    ds            ; save original data segment
  724.     mov    si,savadr        ; offset of storage area
  725.     push    savadr+2        ; segment of same
  726.     pop    ds            ; put storage segment into ds
  727.     cld
  728.     rep    movsw             ; restore data to screen
  729.     pop    ds            ; recover original data segment
  730.     call    fscron            ; turn on screen [dt]
  731.     pop    cx            ; recover count
  732.     call    fscrsync        ; synch Topview with new screen
  733. restsc2:pop    di
  734.     pop    si
  735.     pop    es
  736.     ret
  737. frestscr endp
  738.  
  739. ; Save the screen to a buffer and then append buffer to a disk file. [jrd]
  740. ; Default filename is Kermit.scn; actual file can be a device too. Filename
  741. ; is determined by mssset and is passed as pointer dmpname.
  742. ; Dumpscr reads the screen image saved by savescr so call savescr call first.
  743.  
  744. fdumpscr proc    FAR
  745.     cmp    savadr+2,0        ; any save area?
  746.     jne    dmp6            ; ne = yes
  747.     clc                ; else ignore and return success
  748.     ret
  749. dmp6:    push    ax
  750.     push    bx
  751.     push    cx
  752.     push    dx
  753.     mov    dmphand,-1        ; preset illegal handle
  754.     mov    dx,offset dmpname    ; name of disk file, from mssset
  755.     mov    ax,dx            ; where isfile wants name ptr
  756.     call    fisfile            ; what kind of file is this?
  757.     jc    dmp5            ; c = no such file, create it
  758.     test    byte ptr filtst.dta+21,1fh ; file attributes, ok to write?
  759.     jnz    dmp0            ; nz = no.    
  760.     mov    al,1            ; writing
  761.     mov    ah,open2        ; open existing file
  762.     int    dos
  763.     jc    dmp0            ; c = failure
  764.     mov    dmphand,ax        ; save file handle
  765.     mov    bx,ax            ; need handle here
  766.     mov    cx,0ffffh        ; setup file pointer
  767.     mov    dx,-1            ; and offset
  768.     mov    al,2            ; move to eof minus one byte
  769.     mov    ah,lseek        ; seek the end
  770.     int    dos
  771.     jmp    dmp1
  772.  
  773. dmp5:    test    filtst.fstat,80h    ; access problem?
  774.     jnz    dmp0            ; nz = yes
  775.     mov    ah,creat2        ; file did not exist
  776.     mov    cx,20h            ; attributes, archive bit
  777.     int    dos
  778.     mov    dmphand,ax        ; save file handle
  779.     jnc    dmp1            ; nc = ok
  780.  
  781. dmp0:    call    fgetpos            ; get cursor position
  782.     push    dx            ; save it
  783.     mov    dh,byte ptr low_rgt+1    ; go to status line
  784.     inc    dh
  785.     xor    dl,dl            ; left most column
  786.     call    fsetpos            ; position cursor
  787.     mov    dx,offset dmperr    ; say no can do
  788.     mov    ah,prstr
  789.     int    dos
  790.     pop    dx            ; get original cursor position
  791.     call    fsetpos            ; position cursor
  792.     pop    dx
  793.     pop    cx
  794.     pop    bx
  795.     pop    ax
  796.     clc
  797.     ret
  798.  
  799. dmp1:    mov    ah,ioctl        ; is destination ready for output?
  800.     mov    al,7            ; test output status
  801.     mov    bx,dmphand        ; handle
  802.     int    dos
  803.     jc    dmp0            ; c = error
  804.     cmp    al,0ffh            ; ready?
  805.     jne    dmp0            ; ne = not ready
  806.     push    di            ; read screen buffer, write lines
  807.     push    si
  808.     push    es
  809.     mov    cl,byte ptr low_rgt+1    ; number of lines - 2
  810.     add    cl,2            ; number of line on screen
  811.     xor    ch,ch
  812.     mov    si,savadr        ; offset in storage area
  813. dmp2:    push    cx            ; save outer loop counter
  814.     mov    es,savadr+2        ; get storage segment
  815.     mov    di,offset dumpbuf    ; data segment memory
  816.     mov    cl,byte ptr savflg    ; number of columns on screen
  817.     xor    ch,ch
  818. dmp3:    mov    ax,word ptr es:[si]    ; read char + attribute
  819.     or    al,al            ; is it a null?
  820.     jnz    dmp3c            ; nz = no
  821.     mov    al,' '            ; replace null with space
  822. dmp3c:    mov    byte ptr [di],al    ; store just char, don't use es:
  823.     inc    si            ; update pointers
  824.     inc    si
  825.     inc    di
  826.     loop    dmp3            ; do for each column
  827.     std                ; set scan backward
  828.     mov    cl,byte ptr savflg    ; number of columns on screen
  829.     xor    ch,ch
  830.     push    es
  831.     mov    ax,ds
  832.     mov    es,ax            ; set es to data segment for es:di
  833.     mov    di,offset dumpbuf    ; start of line
  834.     add    di,cx            ; plus length of line
  835.     dec    di            ; minus 1 equals end of line
  836.     mov    al,' '            ; thing to scan over
  837.     repe    scasb            ; scan until non-space
  838.     cld                ; set direction forward
  839.     pop    es
  840.     jz    dmp3a            ; z = all spaces
  841.     inc    cx
  842.     inc    di
  843. dmp3a:    mov    word ptr [di+1],0A0Dh    ; append cr/lf
  844.     add    cx,2            ; line count + cr/lf
  845.     mov    dx,offset dumpbuf    ; array to be written
  846.     mov    bx,dmphand        ; need file handle
  847.     mov    ah,write2        ; write the line
  848.     int    dos
  849.     pop    cx            ; get line counter again
  850.     jc    dmp3b            ; c = error
  851.     loop    dmp2            ; do next line
  852.     mov    dx,offset dumpsep    ; put in formfeed/cr/lf
  853.     mov    cx,3            ; three bytes overall
  854.     mov    ah,write2        ; write them
  855. dmp3b:    mov    bx,dmphand        ; file handle
  856.     int    dos
  857.     mov    ah,close2        ; close the file now
  858.     int    dos
  859.     pop    es
  860.     pop    si
  861.     pop    di
  862.     pop    dx
  863.     pop    cx
  864.     pop    bx
  865.     pop    ax
  866.     clc
  867.     ret
  868. fdumpscr endp
  869. code1    ends
  870.  
  871. code    segment
  872.     assume    cs:code
  873.  
  874. dumpscr    proc    near
  875.     call    fdumpscr
  876.     ret
  877. dumpscr    endp
  878. savescr    proc    near
  879.     call    fsavescr
  880.     ret
  881. savescr    endp
  882. restscr    proc    near
  883.     call    frestscr
  884.     ret
  885. restscr    endp
  886.  
  887. ; do initialization local to this module
  888. ; Dynamically allocates 4000 bytes for screen save/restore buffer plus
  889. ;  320 to 38400 bytes for screen scroll back buffers. Tries to leave space
  890. ;  for Command.com before enlarging buffers. [jrd]
  891. lclyini    proc    near
  892.     call    msuinit            ; initialize keyboard module msuxxx
  893.     mov    ah,conout        ; write a space to determine
  894.     mov    dl,' '            ; DOS's default cursor coloring
  895.     int    dos
  896.     call    getpos            ; get current cursor position into dx
  897.     mov    lincur,cx        ; save cursor type (scan line #'s)
  898.     dec    dl            ; backup to last char
  899.     or    dl,dl
  900.     jns    lclyin5            ; ns = no problem
  901.     xor    dl,dl            ; else set cursor back to left margin
  902. lclyin5:call    setpos            ; set cursor position
  903.     call    getatch            ; read current attributes into AH
  904.     mov    scbattr,ah        ; save video attributes
  905.     mov    savattr,ah        ; and saved attributes
  906.     mov    dosattr,ah        ; and here too
  907.     and    ah,att_intensity    ; select intensity bit
  908.     mov    userbold,ah        ; save bit for user Bold control
  909.     mov    ega_mode,0        ; assume no EGA
  910.     mov    ax,1200H        ; EGA: Bios alternate select
  911.     mov    bl,10H            ; Ask for EGA info
  912.     mov    bh,0ffH            ; Bad info, for testing
  913.     mov    cl,0fH            ; Reserved switch settings
  914.     int    screen            ; EGA, are you there?
  915.     cmp    cl,0cH            ; Test reserved switch settings
  916.     jge    lclyin1            ; ge = no EGA in use
  917.     push    es
  918.     mov    ax,40h            ; check Bios 40:87h for ega being
  919.     mov    es,ax            ;  the active display adapter
  920.     test    byte ptr es:[87h],8    ; is ega active?
  921.     pop    es
  922.     jnz    lclyin1            ; nz = no
  923.     mov    ega_mode,1        ; yes, set flag to say so
  924.     mov    crt_norm,3        ; assume color monitor is attached
  925.     or    bh,bh            ; is color mode in effect?
  926.     jz    lclyin1            ; z = yes
  927.     mov    crt_norm,7        ; else use mode 7 for mono
  928. lclyin1:call    scrseg            ; test running in an Environment
  929.     call    dvtest            ; test for running under DESQview
  930.     call    scrmod            ; read video state, get crt_mode
  931.     mov    ax,low_rgt        ; lower right corner of screen
  932.     mov    al,crt_mode
  933.     mov    crt_norm,al        ; save as normal mode
  934.                     ; screen roll back buffers
  935.     mov    al,crt_lins        ; physical length of user area
  936.     mul    crt_cols        ; physical width
  937.     add    ax,7            ; round up
  938.     mov    cl,3
  939.     shr    ax,cl            ; bytes/screen to paragraphs/screen
  940.     mov    si,ax            ; save a copy in si
  941.     mov    bx,npages        ; number of roll back screens wanted
  942.     inc    bx            ; include current screen in count
  943.     mul    bx            ; total number of screens wanted
  944.     mov    cx,ax            ; save total wanted paragraphs in cx
  945.     mov    bx,0ffffh        ; ask for all of memory, to get size
  946.     mov    ah,alloc        ; allocate all of memory (must fail)
  947.     int    dos            ; bx has # free paragraphs
  948.     mov    ax,bx            ; ax has copy of number free paragraphs
  949.     sub    bx,26000D/16        ; space for Command.com copy #2
  950.     jc    lclyin2            ; c = not enough for it
  951.     cmp    bx,si            ; minimum roll back space left over?
  952.     jbe    lclyin2            ; be = not even that much
  953.     cmp    bx,cx            ; got vs wanted paras for roll back
  954.     jbe    lclyin3            ; be = enough but not more than needed
  955.     mov    bx,cx            ; limit to our actual needs
  956.     jmp    short lclyin3        ; ask for all we really want
  957. lclyin2:xor    bx,bx            ; use no space at all
  958.     mov    cx,bx            ; remember this new request
  959. lclyin3:mov    ah,alloc
  960.     int    dos
  961.     mov    iniseg,ax        ; (BDT) memory segment, window area
  962.     mov    inipara,bx        ; save for later resizing of buffers
  963.     cmp    cx,bx            ; paragraphs wanted vs delivered
  964.     jae    lclyin4            ; ae = enough
  965.     mov    ah,prstr
  966.     mov    dx,offset memerr    ; say not enough memory to operate
  967.     int    dos
  968.     mov    flags.extflg,1        ; set Kermit exit flag
  969. lclyin4:call    bufadj             ; set roll back buffer parameters
  970.     call    vsinit            ; init terminal emulator module MSZ
  971.     mov    bx,vtemu.att_ptr    ; attributes pointer
  972.     mov    ah,dosattr        ; startup video attributes
  973.     and    ah,not att_intensity    ; emulation intensity to normal
  974.     or    ah,userbold
  975.     mov    [bx],ah            ; set initial emulation attributes
  976.     and    vtemu.vtflgst,not deccol ; assume 80 column screen
  977.     and    vtemu.vtflgop,not deccol
  978.     cmp    crt_cols,80        ; screen cols now, wide screen?
  979.     jbe    lclyin6            ; be = no
  980.     or    vtemu.vtflgst,deccol    ; say using 132 columns screen
  981.     or    vtemu.vtflgop,deccol
  982. lclyin6:ret
  983. lclyini    endp
  984.  
  985. ; Determine screen roll back buffer parameters depending on current screen
  986. ; dimensions and available memory. Each rollback screen line has its own
  987. ; segment (lines start on segment boundaries for rollback).
  988.  
  989. bufadj    proc    near
  990.     push    bx
  991.     push    cx
  992.     push    dx
  993.     mov    lxtra,0            ; assume no storage for "extra" lines
  994.     xor    bh,bh            ; (BDT) get bytes / line
  995.     mov    bl,crt_cols        ; (BDT) physical line width
  996.     add    bx,7            ; (BDT) round up to paragraph boundary
  997.     mov    cl,3            ; (BDT) now convert to
  998.     shr    bx,cl            ; (BDT) paragraphs / line
  999.     mov    ppl,bx            ; (BDT) save this in buffer area
  1000.     mov    ax,inipara        ; (BDT) compute the number of lines
  1001.     xor    dx,dx
  1002.     div    bx            ; (BDT)  in the buffer
  1003.     mov    lmax,ax            ; max line capacity of the buffer
  1004.     mov    linee,ax        ; (BDT) save as number of total lines
  1005.     or    ax,ax            ; is this zero?
  1006.     jz    bufadj1            ; z = yes, no space at all
  1007.     xor    bh,bh            ; (BDT) get lines / screen
  1008.     mov    bl,byte ptr low_rgt+1    ; (BDT) rows on user/host screen
  1009.     inc    bx            ; (BDT) adjust for counting from 0
  1010.     mov    lxtra,bx        ; (BDT) save as "extra" lines
  1011.     sub    lmax,bx            ; (BDT) deduct "extra" lines req'd
  1012.     jg    bufadj1            ; g = have some rollback space
  1013.     mov    lmax,0            ; say none
  1014.     mov    lxtra,0            ; say none of these too
  1015. bufadj1:mov     lcnt,0                  ; (BDT) # of lines filled in buffer
  1016.     mov    linef,0            ; (BDT) first filled in line
  1017.     mov    linec,0            ; (BDT) last  filled in line
  1018.     pop    dx
  1019.     pop    cx
  1020.     pop    bx
  1021.     ret
  1022. bufadj    endp
  1023.  
  1024.  
  1025.                     ; begin Terminal set & status code
  1026. ; SET Term parameters, especially for use with VT100 emulator. [jrd]
  1027. ; Taken from work done originally by James Harvey IUPUI.
  1028. ; VTS is called only by mssset to set terminal type and characteristics.
  1029. ; Enter via direct jmp. Exit carry set for failure.
  1030. VTS    proc    near            ; SET TERM whatever
  1031.     mov    ah,cmkey        ; Parse another keyword
  1032.     mov    bx,offset vthlp        ; Use this help
  1033.     mov    dx,offset vttbl        ; Use this table
  1034.     call    comnd
  1035.     jnc    vset1            ; nc = success
  1036.     ret                ; failure
  1037. vset1:    cmp    bh,81H            ; marker for terminal type?
  1038.     je    vsetu0            ; e = yes
  1039.     cmp    bh,82h            ; marker for set term color?
  1040.     jne    vset1a            ; ne = no
  1041.     jmp    vsetu2            ; e = yes
  1042. vset1a:    cmp    bh,83h            ; marker for character set?
  1043.     jne    vset1f            ; ne = no
  1044.     jmp    vsetu3            ; e = yes
  1045. vset1f:    cmp    bh,84h            ; marker for roll back control?
  1046.     jne    vset1g            ; ne = no
  1047.     jmp    vsetu4            ; e = yes
  1048. vset1g:    cmp    bh,85h            ; marker for clear-screen?
  1049.     jne    vset1b            ; ne = no
  1050.     mov    ah,cmeol        ; yes
  1051.     call    comnd
  1052.     jc    vset1h            ; c = failure
  1053.     mov    vtclear,2        ; set trigger for emulator clear scn
  1054.     clc                ; success
  1055. vset1h:    ret
  1056.  
  1057. vset1b:    cmp    bh,86h            ; marker for graphics type?
  1058.     jne    vset1c            ; ne = no
  1059.     jmp    vsetu8            ; yes
  1060.  
  1061. vset1c:    cmp    bh,87h            ; marker for REPLAY?
  1062.     jne    vset1d            ; ne = no
  1063.     jmp    REPLAY            ; yes, do REPLAY
  1064. vset1d:    cmp    bh,88h            ; marker for BELL?
  1065.     jne    vset1i            ; ne = no
  1066.     jmp    vsetu10            ; yes, do BELL setup
  1067. vset1i:    cmp    bh,89h            ; SET TERM DISPLAY / BYTESIZE?
  1068.     jne    vset1j            ; ne = no
  1069.     jmp    vsetu11            ; do command
  1070. vset1j:    cmp    bh,8Ah            ; SET TERM UPSS?
  1071.     jne    vsetu1            ; ne = no
  1072.     jmp    vsetu12
  1073. vsetu1:    jmp    vtrtns[bx]        ; Dispatch
  1074.  
  1075. vsetu0:    cmp    bx,81ffh        ; just SET TERM TYPE?
  1076.     jb    vsetu0f            ; b = no, have kind
  1077.     mov    ah,cmkey        ; parse another keyword
  1078.     xor    bx,bx            ; table is help
  1079.     mov    dx,offset termtb    ; use this table
  1080.     call    comnd
  1081.     jnc    vsetu0f            ; nc = success
  1082.     ret                ; failure
  1083. vsetu0f:mov    byte ptr temp,bl    ; set terminal type
  1084.     mov    byte ptr temp+1,-1    ; assume no enable/disable Tek
  1085.     cmp    bl,tttek        ; set term tek?
  1086.     jne    vsetu0a            ; ne = no
  1087.     mov    dx,offset disatab    ; disable/enable keyword table
  1088.     xor    bx,bx            ; help is the table
  1089.     mov    comand.cmcr,1        ; allow bare CR's
  1090.         mov    ah,cmkey        ; get enable/disable keyword
  1091.     call    comnd
  1092.     mov    comand.cmcr,0        ; no more bare CR's
  1093.     jc    vsetu0e            ; c = no such keyword
  1094.     mov    byte ptr temp+1,bl    ; save enable/disable keyword value
  1095.     mov    bl,flags.vtflg        ; get current terminal type
  1096.     mov    byte ptr temp,bl    ; and force it here
  1097.  
  1098. vsetu0a:mov    ah,cmeol
  1099.     call    comnd            ; get a confirm
  1100.     jc    vsetu0d            ; c = failure
  1101. vsetu0e:mov    bx,temp
  1102.     mov    flags.vtflg,bl        ; Set the terminal emulation type
  1103.     mov    tekflg,0        ; clear Tek sub mode
  1104.     cmp    bl,tttek        ; adjusting Tek?
  1105.     je    vsetu0b            ; e = yes
  1106.     cmp    bh,-1            ; just enable/disable tek?
  1107.     je    vsetu0c            ; e = no
  1108. vsetu0b:and    denyflg,not tekxflg    ; enable Tek
  1109.     cmp    bh,1            ; ought we disable?
  1110.     jne    vsetu0c            ; ne = no
  1111.     or    denyflg,tekxflg        ; disable Tek
  1112. vsetu0c:clc                ; success
  1113. vsetu0d:ret
  1114.  
  1115. vsetu3: mov    ah,cmkey        ; Set Term character set
  1116.     xor    bx,bx            ; character set table for help 
  1117.     mov    temp,bx            ; counter of trailing items
  1118.     mov    dx,offset chatab    ; character set table
  1119.     call    comnd
  1120.     jc    vsetu0d            ; c = failure
  1121.     mov    dumpbuf,bl        ; save here
  1122.     mov    ax,word ptr vtemu.vttable ; table of 4 overrides now
  1123.     mov    word ptr dumpbuf+1,ax    ; copy them to temporary table
  1124.     mov    ax,word ptr vtemu.vttable+2
  1125.     mov    word ptr dumpbuf+3,ax
  1126. vsetu3a:mov    comand.cmcr,1        ; allow bare CR's
  1127.     mov    ah,cmkey
  1128.     xor    bx,bx
  1129.     mov    dx,offset sidetab    ; read Gnumber item, if any
  1130.     call    comnd
  1131.     mov    comand.cmcr,0        ; no bare CR's
  1132.     jc    vsetu3b            ; c = no match, get confirm
  1133.     inc    temp            ; say have a trailing table number
  1134.     and    bx,3            ; remove value encoding
  1135.     add    bx,offset dumpbuf+1    ; address of slot to store info
  1136.     mov    al,dumpbuf        ; set ident
  1137.     mov    [bx],al            ; store table ident in G0..G3 slot
  1138.     jmp    short vsetu3a        ; repeat
  1139. ; vtemu.vtchset:    changed to new set if no table trailers, else intact
  1140. ; vtemu.vttable    db 4 dup(0ffh)     char set numbers for G0..G3 as overrides,
  1141. ;                use 0ffh to mean no override for table Gn
  1142. vsetu3b:mov    ah,cmeol        ; get EOL confirmation
  1143.     call    comnd
  1144.     jc    vsetu3d            ; c = failure, quit
  1145.     mov    vtemu.vtchop,0ffh    ; say reinit char tables
  1146.     cmp    temp,0            ; trailers (skip regular setup)?
  1147.     jne    vsetu3c            ; ne = yes
  1148.     mov    al,dumpbuf        ; get character set
  1149.     mov    vtemu.vtchset,al    ; set default character set
  1150.                     ; just overrides
  1151. vsetu3c:mov    ax,word ptr dumpbuf+1    ; first pair of char set idents
  1152.     mov    word ptr vtemu.vttable,ax
  1153.     mov    ax,word ptr dumpbuf+3    ; second pair
  1154.     mov    word ptr vtemu.vttable+2,ax
  1155.     clc
  1156. vsetu3d:ret
  1157.  
  1158. vsetu4:    mov    ah,cmkey        ; Set Term Roll On/Off, auto roll back
  1159.     xor    bx,bx            ; Use on/off table as help
  1160.     mov    dx,offset ontab        ; Use on/off table
  1161.     call    comnd
  1162.     jc    vsetu4a            ; c = failure
  1163.     mov    temp,bx
  1164.     mov    ah,cmeol        ; get a confirm
  1165.     call    comnd
  1166.     jc    vsetu4a            ; c = failure
  1167.     mov    bx,temp
  1168.     mov    vtroll,bl        ; set roll state (0=no auto rollback)
  1169.     clc
  1170. vsetu4a:ret
  1171.  
  1172.                      ; Set Term Color foreground, background
  1173. vsetu2:    mov    bx,vtemu.att_ptr    ; get address of attributes byte
  1174.     mov    bl,[bx]            ; get attributes
  1175.     mov    dumpbuf,bl        ; save in work temp
  1176.     mov    al,vtclear        ; screen clear state
  1177.     mov    ah,refresh        ; refresh state
  1178.     mov    word ptr dumpbuf+1,ax    ; save here
  1179.     call    vsetcol            ; get and analyze colors
  1180.     jc    vsetu2a            ; c = failure
  1181.     mov    al,dumpbuf        ; get current attributes
  1182.     mov    bx,vtemu.att_ptr    ; get address of attributes byte
  1183.     mov    [bx],al            ; store attributes
  1184.     mov    ax,word ptr dumpbuf+1
  1185.     mov    vtclear,al        ; update these items
  1186.     mov    refresh,ah
  1187.     clc
  1188. vsetu2a:ret
  1189.                     ; setup color information
  1190. vsetcol:mov    ah,cmword        ; get number(s) after set term color
  1191.     mov    bx,offset colhlp    ; use this help
  1192.     mov    dx,offset rdbuf        ; temp buffer
  1193.     mov    rdbuf,0            ; clear the buffer
  1194.     mov    comand.cmcr,1        ; allow bare c/r's
  1195.     call    comnd
  1196.     jc    vsetco2            ; c = failure
  1197.     or    ax,ax            ; text given?
  1198.     jz    vsetco1            ; z = no
  1199.     mov    si,offset rdbuf        ; si = place where atoi wants text
  1200.     call    vsetco3            ; analyze
  1201.     jmp    short vsetcol        ; get more data
  1202. vsetco1:mov    ah,cmeol        ; get end of line confirm
  1203.     call    comnd
  1204. vsetco2:ret                ; c set if failure
  1205.  
  1206.  
  1207. vsetco3:mov    dx,si
  1208.     call    strlen            ; get count for atoi
  1209.     mov    ah,cl            ; count for atoi
  1210.     call    atoi            ; convert text to numeric in ax
  1211.     jnc    vsetco3a        ; got a value
  1212.     ret                ; out of data
  1213. vsetco3a:or    ax,ax            ; reset all? regular IBM CGA refresh
  1214.     jnz    vsetco4            ; nz = no
  1215.     mov    dumpbuf+2,0        ; Regular (slow) screen refresh
  1216.     mov    dumpbuf,07h        ; clear all, set white on black
  1217.     mov    dumpbuf+1,2        ; set trigger for emulator clear scrn
  1218.     jmp    short vsetco3
  1219.  
  1220. vsetco4:cmp    ax,1            ; high intensity?
  1221.     jne    vsetco5            ; e = no
  1222.     or    dumpbuf,08h        ; set high intensity
  1223.     mov    dumpbuf+1,1        ; set trigger for emulator keep screen
  1224.     jmp    short vsetco3
  1225.  
  1226. vsetco5:cmp    ax,10            ; fast refresh?
  1227.     jne    vsetco6            ; ne = no
  1228.     mov    dumpbuf+2,1        ; Fast screen refresh
  1229.     jmp    short vsetco3
  1230.  
  1231. vsetco6:cmp    ax,30            ; check range
  1232.     jb    vsetco8            ; b = too small, complain
  1233.     cmp    ax,37
  1234.     ja    vsetco7            ; 30-37 is foreground color
  1235.     sub    al,30            ; remove foreground bias
  1236.     and    dumpbuf,not 07H        ; clear foreground bits
  1237.     mov    bx,ax
  1238.     mov    al,colortb[bx]        ; get reversed bit pattern
  1239.     or    dumpbuf,al        ; load new bits
  1240.     mov    dumpbuf+1,2        ; set trigger for emulator clear scn
  1241.     jmp    short vsetco3
  1242.  
  1243. vsetco7:cmp    ax,40
  1244.     jb    vsetco8            ; b = bad value
  1245.     cmp    ax,47            ; compare as unsigned
  1246.     ja    vsetco8            ; 40-47 is background
  1247.     sub    al,40            ; remove background bias
  1248.     and    dumpbuf,not 70H        ; clear background bits
  1249.     mov    bx,ax
  1250.     mov    al,colortb[bx]        ; get reversed bit pattern
  1251.     mov    cl,4            ; rotate 4 positions
  1252.     rol    al,cl
  1253.     or    dumpbuf,al        ; load new bits
  1254.     mov    dumpbuf+1,2        ; set trigger for emulator clear scn
  1255.     jmp    vsetco3
  1256.  
  1257. vsetco8:mov    ah,prstr        ; not in range - complain and exit
  1258.     mov    dx,offset colerr
  1259.     int    dos
  1260.     stc                ; error
  1261.     ret
  1262.          
  1263.  
  1264. vsetu8:    mov    ah,cmkey        ; Set Term graphics
  1265.     xor    bx,bx            ; Use graphics table as help
  1266.     mov    dx,offset graftab    ; Use graphics table
  1267.     call    comnd
  1268.     jc    vsetu8a            ; c = failure
  1269.     mov    temp,bx
  1270.     cmp    bx,100h            ; in the special options area?
  1271.     ja    vsetu8b            ; a = yes
  1272.     mov    ah,cmeol        ; get a confirm
  1273.     call    comnd
  1274.     jc    vsetu8a            ; c = failure
  1275.     mov    bx,temp
  1276.     mov    tekgraf,bl        ; set Tek graphics board type
  1277.     clc
  1278. vsetu8a:ret
  1279. vsetu8b:cmp    bx,101h            ; character writing?
  1280.     jne    vsetu8c
  1281.     mov    ah,cmkey        ; Set Term graphics char-writing
  1282.     xor    bx,bx            ; no help
  1283.     mov    dx,offset gchrtab    ; opaque/transparent table
  1284.     call    comnd
  1285.     jc    vsetu8a            ; c = failure
  1286.     push    bx
  1287.     mov    ah,cmeol        ; get a confirm
  1288.     call    comnd
  1289.     pop    bx
  1290.     jc    vsetu8a
  1291.     mov    chcontrol,bl        ; set/reset opaque char control
  1292.     clc
  1293.     ret
  1294. vsetu8c:cmp    bx,102h            ; cursor on/off?
  1295.     jne    vsetu8e            ; ne = no
  1296.     mov    ah,cmkey        ; Set Term graphics cursor on/off
  1297.     xor    bx,bx            ; no help
  1298.     mov    dx,offset ontab        ; on/off table
  1299.     call    comnd
  1300.     jc    vsetu8d            ; c = failure
  1301.     push    bx
  1302.     mov    ah,cmeol        ; get a confirm
  1303.     call    comnd
  1304.     pop    bx
  1305.     jc    vsetu8d
  1306.     mov    tekcursor,bl        ; set Tek text cursor on/off
  1307.     clc
  1308. vsetu8d:ret
  1309.  
  1310. vsetu8e:cmp    bx,103h            ; Color?
  1311.     jne    vsetu8d            ; ne = no
  1312.     call    tekgcptr        ; get pointer to active Tek color pal
  1313.     mov    al,[bx]            ; get background attributes
  1314.     and    al,7            ; discard intensity bit
  1315.     mov    cl,4
  1316.     shl    al,cl
  1317.     mov    ah,[bx+7]        ; get foreground attributes
  1318.     or    al,ah
  1319.     mov    dumpbuf,al        ; setup work temp for vsetcol
  1320.     push    bx            ; save index
  1321.     call    vsetcol            ; get and analyze colors
  1322.     pop    bx
  1323.     jnc    vsetu8f            ; nc = ok
  1324.     ret
  1325. vsetu8f:mov    al,dumpbuf        ; get current attributes
  1326.     mov    ah,al            ; get background bits
  1327.     mov    cl,4
  1328.     shr    ah,cl            ; just background here
  1329.     and    al,0fh            ; just foreground here
  1330.     mov    [bx],ah            ; store colpal[0] as background
  1331.     mov    [bx+7],al        ; store colpal[7] as foreground
  1332.     clc                ; success
  1333.     ret
  1334.     
  1335. vsetu10:mov    ah,cmkey        ; SET TERM BELL
  1336.     xor    bx,bx            ; use table as help
  1337.     mov    dx,offset beltab    ; use Bell table
  1338.     call    comnd
  1339.     jc    vsetu10a        ; c = failure
  1340.     mov    temp,bx
  1341.     mov    ah,cmeol        ; get a confirm
  1342.     call    comnd
  1343.     jc    vsetu10a        ; c = failure
  1344.     mov    bx,temp
  1345.     mov    belltype,bl        ; set bell type
  1346. vsetu10a:ret                ; return carry clear or set
  1347.  
  1348.                     ; SET TERM BYTESIZE {7-bit | 8-bit}
  1349. vsetu11:mov    ah,cmkey        ; SET TERM DISPLAY {7-bit | 8-bit}
  1350.     mov    dx,offset distab    ; table
  1351.     xor    bx,bx            ; help is table
  1352.     call    comnd
  1353.     jc    vsetu11a        ; c = failure
  1354.     push    bx
  1355.     mov    ah,cmeol        ; get a confirm
  1356.     call    comnd
  1357.     pop    bx
  1358.     jc    vsetu11a        ; c = failure
  1359.     and    flags.remflg,not d8bit    ; clear display 8-bit bit
  1360.     or    flags.remflg,bl        ; set or clear the bit
  1361. vsetu11a:ret
  1362.  
  1363. vsetu12:mov    ah,cmkey        ; SET TERM UPSS
  1364.     mov    bx,offset upsshlp    ; help
  1365.     mov    dx,offset upsstab    ; UPSS table
  1366.     call    comnd            ; get UPSS char set
  1367.     jc    vsetu12b        ; failure
  1368.     push    bx
  1369.     mov    ah,cmeol
  1370.     call    comnd
  1371.     pop    bx
  1372.     jc    vsetu12b        ; c = fail
  1373.     mov    ax,'5%'            ; assume DEC Supplemental Graphics/94
  1374.     cmp    bx,94            ; Dec Supp Graphics?
  1375.     je    vsetu12a        ; ne = no
  1376.     mov    ax,'A'            ; Latin-1
  1377. vsetu12a:mov    upss,bl            ; set length
  1378.     mov    word ptr upss+1,ax    ; store set ident
  1379.     mov    vtemu.vtchop,0        ; clear operational char set to reinit
  1380.     clc
  1381. vsetu12b:ret
  1382.  
  1383. ; SET Term flags. These are the (near) equivalent of VT100 Setup mode values.
  1384.      
  1385. flgset:    push    bx            ; save index (newval etc)
  1386.     mov    ah,cmkey        ; Another keyword
  1387.     mov    dx,vtable[bx]        ; The table to use
  1388.     xor    bx,bx            ; Use default help
  1389.     call    comnd
  1390.     mov    temp,bx            ; save switch value
  1391.     pop    bx            ; recover index
  1392.     jc    flgse0            ; c = failure
  1393.     push    bx
  1394.     mov    ah,cmeol        ; get confirm
  1395.     call    comnd
  1396.     pop    bx
  1397.     jc    flgse0            ; c = failure
  1398.     mov    dx,temp            ; Restore switch value
  1399.     mov    ax,vtsflg[bx]        ; get the flag
  1400.     or    dx,dx            ; set or clear?
  1401.     je    flgse1            ; e = clear it
  1402.     or    vtemu.vtflgst,ax    ; set the flag
  1403.     or    vtemu.vtflgop,ax    ; in runtime flags too
  1404. flgse3:    test    ax,deccol        ; modifying screen width?
  1405.     jz    flgse2            ; z = no
  1406.     mov    al,crt_cols        ; current width
  1407.     mov    dos_cols,al        ; width to remember, for changes
  1408. flgse2:    clc                ; success
  1409. flgse0:    ret     
  1410. flgse1: not    ax            ; Complement
  1411.     and    vtemu.vtflgst,ax    ; clear the indicated setup flag
  1412.     and    vtemu.vtflgop,ax    ; clear the indicated runtime flag
  1413.     not    ax
  1414.     jmp    short flgse3        ; test for screen change
  1415.      
  1416. ;    SET Term Tabstops Clear ALL
  1417. ;    SET Term Tabstops Clear AT n1, n2, ..., nx
  1418. ;    SET Term Tabstops At n1, n2, ..., nx
  1419.      
  1420. tabmod:    mov    ah,cmkey        ; parse keyword
  1421.     mov    bx,offset clrhlp    ; help text
  1422.     mov    dx,offset tabtab    ; table
  1423.     call    comnd
  1424.     jc    tabmo2            ; c = failure
  1425.     mov    clrset,2        ; 2 = code for set a tab
  1426.     or    bl,bl            ; clear?
  1427.     jnz    tabmo4            ; nz = no, SET. parse column number(s)
  1428.     mov    clrset,1        ; code for clear at/all tab(s)
  1429.     mov    ah,cmkey        ; CLEAR, parse ALL or AT
  1430.     mov    bx,offset clrhlp    ; help text
  1431.     mov    dx,offset alltab    ; parse ALL or AT
  1432.     call    comnd
  1433.     jc    tabmo2            ; c = failure
  1434.     or    bx,bx            ; ALL?
  1435.     jnz    tabmo4            ; nz = AT, clear at specific places
  1436.     mov    ah,cmeol        ; confirm the ALL
  1437.     call    comnd
  1438.     jc    tabmo2            ; c = failure
  1439.     mov    cx,132            ; ALL, means clear all tab stops
  1440. tabmo1:    mov    dx,cx
  1441.     dec    dl            ; column number, starting with 0
  1442.     mov    si,vtemu.vttbs        ; the cold-start buffer
  1443.     call    tabclr            ; clear the tab
  1444.     loop    tabmo1            ; do all columns
  1445.     mov    si,vtemu.vttbs
  1446.     mov    di,vtemu.vttbst        ; and active buffer
  1447.     call    tabcpy            ; update active tabs
  1448.     clc                ; success
  1449. tabmo2:    ret                ; a success/fail return point
  1450.  
  1451. tabmo4:    mov    si,vtemu.vttbs        ; from the cold-start buffer
  1452.     mov    di,offset decbuf    ; temp work buffer
  1453.     call    tabcpy            ; make a working copy of the tabs
  1454.     mov    skip,0            ; clear spacing-active flag
  1455.     mov    temp,0            ; place where last tab was written
  1456. tabmo6:    mov    bx,offset clrhlp2    ; tell them we want a column number
  1457.     mov    ah,cmword        ; get line of text
  1458.     mov    dx,offset rdbuf        ; temp buffer
  1459.     call    comnd
  1460.     jc    tabmo2            ; c = failure
  1461.     or    ax,ax            ; anything given?
  1462.     jnz    tabmo7            ; nz = yes
  1463.     mov    ah,cmeol        ; confirm end of line
  1464.     call    comnd
  1465.     jc    tabmo2            ; failure
  1466.     mov    si,offset decbuf    ; copy tabs from temp work buffer
  1467.     mov    di,vtemu.vttbs        ; to the cold-start buffer
  1468.     call    tabcpy            ; copy work to cold start
  1469.     mov    di,vtemu.vttbst        ; and terminal emulator's active buf
  1470.     call    tabcpy
  1471.     clc
  1472.     ret
  1473.  
  1474. tbsbad:    mov    ah,prstr        ; not in range - complain
  1475.     mov    dx,offset tbserr
  1476.     int    dos
  1477.     stc
  1478.     ret
  1479.      
  1480. tabmo7:    mov    si,offset rdbuf        ; si = place where atoi wants text
  1481. tabmo8:    mov    dx,si
  1482.     call    strlen            ; get length of this word
  1483.     jcxz    tabmo6            ; empty, get more user input
  1484.     mov    ah,cl            ; where atoi wants length
  1485.     call    atoi            ; convert text to numeric in ax
  1486.     jnc    tabmo9            ; nc = successful
  1487.     cmp    byte ptr [si],':'    ; spacing separator?
  1488.     jne    tbsbad            ; ne = no, no number available
  1489.     inc    si            ; skip colon, do start:space analysis
  1490.     inc    skip            ; set spacing-active flag
  1491.     jmp    short tabmo8        ; get another token
  1492.  
  1493. tabmo9:    cmp    skip,0            ; want spacing value now?
  1494.     jne    tabmo11            ; ne = yes, go do it
  1495.     mov    dx,ax            ; column (1-132 style)
  1496.     dec    dx            ; put column in range 0-131
  1497.     or    dx,dx            ; check range (1-132 --> 0-131)
  1498.     jl    tbsbad            ; l = too small. complain
  1499.     cmp    dl,132-1        ; more than the right most column?
  1500.     ja    tbsbad            ; a = yes, quit
  1501.     mov    temp,dx            ; remember last written position
  1502.     jmp    tabmo15            ; and write this member
  1503.  
  1504. tabmo11:mov    dx,temp            ; continue spacing analysis
  1505.     mov    skip,0            ; clear spacing-active flag
  1506.     mov    cx,ax            ; "space" value
  1507.     or    cx,cx            ; zero spacing?
  1508.     jnz    tabmo12            ; nz = no
  1509.     inc    cx            ; don't get caught with zero spacing
  1510. tabmo12:cmp    dx,132-1        ; largest tab stop
  1511.     ja    tabmo8            ; a = done largest tab stop
  1512.     mov    temp,dx            ; remember last written tabstop
  1513.     push    si
  1514.     mov    si,offset decbuf    ; the work buffer
  1515.     cmp    clrset,2        ; set?
  1516.     jne    tabmo13            ; ne = no, clear
  1517.     call    tabset            ; set tabstop in column DL
  1518.     jmp    short tabmo14
  1519. tabmo13:call    tabclr            ; clear tabstop in column DL
  1520. tabmo14:add    dx,cx            ; new column value
  1521.     pop    si
  1522.     jmp    short tabmo12        ; finish spacing loop
  1523.  
  1524. tabmo15:push    si            ; individual tabstop
  1525.     mov    si,offset decbuf    ; the work buffer
  1526.     cmp    clrset,2        ; set?
  1527.     jne    tabmo16            ; ne = no, clear
  1528.     call    tabset            ; set tabstop in column DL
  1529.     jmp    short tabmo17        ; get next command value
  1530. tabmo16:call    tabclr            ; clear tabstop in column DL
  1531. tabmo17:pop    si
  1532.     jmp    tabmo8            ; get next command value
  1533.  
  1534. tabcpy:    push    es            ; worker copy routine
  1535.     push    si
  1536.     push    di
  1537.     mov    cx,ds
  1538.     mov    es,cx
  1539.     mov    cx,(132+7)/8        ; update all active tab stops
  1540.     cld
  1541.     rep    movsb
  1542.     pop    di
  1543.     pop    si
  1544.     pop    es
  1545.     clc                ; success
  1546.     ret
  1547. VTS    endp                ; end of Set Term things
  1548.  
  1549.           ; Terminal Status display, called within STAT0: in MSSSET
  1550. VTSTAT    proc    near            ; enter with di within sttbuf, save bx
  1551.     mov    bx,offset vtstbl    ; table of things to show
  1552.     jmp    statc            ; status common code, in mssset
  1553.  
  1554. colstat    proc    near            ; foreground/background color status
  1555.     push    si
  1556.     mov    si,offset colst1
  1557.     cld
  1558. colstd1:lodsb
  1559.     cmp    al,'$'            ; end of string?
  1560.     je    colstd2            ; e = yes
  1561.     stosb
  1562.     jmp    short colstd1
  1563. colstd2:mov    bx,vtemu.att_ptr    ; pointer to attributes byte
  1564.     mov    bl,byte ptr[bx]
  1565.     xor    bh,bh
  1566.     push    bx
  1567.     and    bx,7            ; get foreground set
  1568.     mov    al,colortb[bx]        ; get reversed bit pattern
  1569.     add    al,'0'            ; add ascii bias
  1570.     stosb
  1571.     pop    bx
  1572.     mov    si,offset colst2
  1573. colstd3:lodsb
  1574.     cmp    al,'$'
  1575.     je    colstd4
  1576.     stosb
  1577.     jmp    short colstd3
  1578. colstd4:mov    cl,4            ; rotate 4 positions
  1579.     shr    bl,cl
  1580.     and    bx,7            ; get background set
  1581.     mov    al,colortb[bx]        ; get reversed bit pattern
  1582.     add    al,'0'            ; add ascii bias
  1583.     stosb
  1584.     pop    si
  1585.     ret    
  1586. colstat    endp
  1587.                     ; Tabs Status display
  1588. tabstat    proc    near            ; display tabs ruler for Status
  1589.     push    dx
  1590.     cld
  1591.     mov    al,cr
  1592.     stosb
  1593.     cmp    cl,10            ; are we on a new line?
  1594.     jb    tabsta0            ; b = no, do a lf now
  1595.     mov    al,lf
  1596.     stosb
  1597. tabsta0:xor    cl,cl            ; column index
  1598.     xor    ax,ax            ; ah = tens, al = units counter
  1599. tabsta1:mov    dl,'.'            ; default position symbol
  1600.     inc    al
  1601.     cmp    al,10            ; time to roll over?
  1602.     jb    tabsta2            ; b = not yet
  1603.     xor    al,al            ; modulo 10
  1604.     inc    ah
  1605.     mov    dl,ah            ; display a tens-digit
  1606.     add    dl,'0'
  1607.     cmp    dl,'9'            ; larger than 90?
  1608.     jbe    tabsta2            ; be = no
  1609.     sub    dl,10            ; roll over to 0, 1, etc
  1610. tabsta2:push    dx
  1611.     push    si
  1612.     mov    dl,cl            ; column number, counted from 0
  1613.     mov    si,vtemu.vttbst        ; the active buffer
  1614.     call    istabs            ; is tab set here?
  1615.     pop    si
  1616.     pop    dx
  1617.     jnc    tabsta3            ; nc = no
  1618.     mov    dl,'T'            ; yes, display a 'T'
  1619. tabsta3:push    ax
  1620.     mov    al,dl
  1621.     stosb
  1622.     pop    ax
  1623.     inc    cl
  1624.     cmp    cl,byte ptr low_rgt    ; done yet?
  1625.     jb    tabsta1            ; b = not yet
  1626.     pop    dx
  1627.     ret
  1628. tabstat    endp
  1629.  
  1630. filler    proc    near            ; use space
  1631.     mov    cx,20
  1632.     mov    al,' '
  1633.     cld
  1634.     rep    stosb
  1635.     ret
  1636. filler    endp
  1637. VTSTAT    endp                ; end of Terminal set & status code
  1638.  
  1639.  
  1640. scrini    proc    near            ; init screen stuff
  1641.     mov    ega_mode,0        ; assume no EGA
  1642.     mov    ax,1200H        ; EGA: Bios alternate select
  1643.     mov    bl,10H            ; Ask for EGA info
  1644.     mov    bh,0ffH            ; Bad info, for testing
  1645.     mov    cl,0fH            ; Reserved switch settings
  1646.     int    screen            ; EGA, are you there?
  1647.     cmp    cl,0cH            ; Test reserved switch settings
  1648.     jge    scrin1            ; ge = no EGA in use
  1649.     push    es
  1650.     mov    ax,40h            ; check Bios 40:87h for ega being
  1651.     mov    es,ax            ;  the active display adapter
  1652.     test    byte ptr es:[87h],8    ; is ega active?
  1653.     pop    es
  1654.     jnz    scrin1            ; nz = no
  1655.     mov    ega_mode,1        ; yes, set flag to say so
  1656.     mov    crt_norm,3        ; assume color monitor is attached
  1657.     or    bh,bh            ; is color mode in effect?
  1658.     jz    scrin1            ; z = yes
  1659.     mov    crt_norm,7        ; else use mode 7 for mono
  1660. scrin1:    call    scrseg            ; update screen segment tv_seg(s/o)
  1661.     call    scrmod            ; get screen mode, low_rgt
  1662.     call    getpos            ; get cursor position and type
  1663.     jcxz    scrin2            ; z = nothing there, skip this
  1664.     mov    lincur,cx        ; save cursor type (scan line #'s)
  1665. scrin2:    mov    bx,vtemu.att_ptr
  1666.     mov    ah,[bx]
  1667.     and    ah,att_intensity
  1668.     mov    userbold,ah        ; remember old bold
  1669.     mov    ax,word ptr crt_cols    ; present screen text size
  1670.     cmp    ax,savflg        ;  vs size of saved screen
  1671.     je    scrin3            ; e = same, do not re-initialize
  1672.                     ;
  1673.     call    bufadj            ; re-initialize screen buffers
  1674.     mov    cursor,0        ; cursor to upper left corner
  1675.     cmp    flags.vtflg,0        ; terminal type of None?
  1676.     ja    scrin3            ; a = no, emulating
  1677.     mov    dh,byte ptr low_rgt+1
  1678.     inc    dh            ; bottom
  1679.     xor    dl,dl            ;  left corner
  1680.     mov    cursor,dx        ; non-emulating cursor
  1681.                     ; Common finish code
  1682. scrin3:    mov    ah,savattr        ; saved emulator attributes
  1683.     mov    scbattr,ah        ; restore active value
  1684.     mov    dx,cursor        ; use old cursor, if any
  1685.     call    setpos            ; set cursor position
  1686.     call    restscr            ; restore screen, if any saved
  1687.     cmp    vtinited,inited        ; inited emulator yet?
  1688.     je    scrin11            ; e = yes
  1689. scrin10:call    vtinit            ; init it now
  1690.     jmp    short scrin13
  1691. scrin11:call    ansrei            ; reinit the emulator
  1692.     cmp    flags.vtflg,tttek    ; Tek mode?
  1693.     je    scrin12            ; e = yes
  1694.     test    tekflg,1        ; Tek mode?
  1695.     jz    scrin13            ; z = no
  1696. scrin12:call    tekini
  1697. scrin13:mov    al,flags.vtflg        ; current terminal type
  1698.     mov    trmtyp,al        ; place to remember it til next time
  1699.     mov    vtclear,0        ; clear the clear-screen flag
  1700.     ret
  1701. scrini    endp
  1702.  
  1703. ; Routine to initialize VT102/52/Heath-19 terminal emulator.
  1704.      
  1705. vtinit    proc    near
  1706.     mov    holdscr,0        ; clear holdscreen
  1707.     call    kbhold            ; tell DEC LK250 the state, in msuibm
  1708.     or    vtinited,inited
  1709.     mov    bx,argadr        ; address of argument block
  1710.     mov    dl,[bx].flgs
  1711.     and    dl,lclecho        ; local echo flag
  1712.     and    yflags,not lclecho
  1713.     or    yflags,dl
  1714.     mov    dl,[bx].baudb        ; baud rate code in dl
  1715.     mov    dh,[bx].parity        ; parity code in bits
  1716.     mov    cl,4            ; 0-3 of dh
  1717.     shl    dh,cl
  1718.     or    dh,07H            ; just say 7 data bits
  1719.     test    flags.remflg,d8bit    ; eight bit display?
  1720.     jz    vtini1            ; z = no
  1721.     inc    dh            ; set low four bits to value 8
  1722. vtini1:    cmp    flags.vtflg,0        ; doing emulation?
  1723.     je    vtini3            ; e = no
  1724.     test    tekflg,1        ; Tek sub-mode active?
  1725.     jnz    vtini2            ; nz = yes, do it's reinit
  1726.     call    ansini            ; call startup routine in mszibm
  1727.     cmp    flags.vtflg,tttek    ; full Tek mode?
  1728.     je    vtini2            ; e = yes
  1729. vtinix:    clc
  1730.     ret
  1731. vtini2:    call    tekrint            ; reinitialize Tek emulator
  1732.     clc
  1733.     ret
  1734. vtini3:    call    cmblnk            ; clear the screen
  1735.     clc
  1736.     ret
  1737. vtinit    endp
  1738.  
  1739. argini    proc    near            ; read passed arguments
  1740.     mov    bx,argadr        ; base of argument block
  1741.     mov    al,[bx].flgs        ; get flags
  1742.     and    al,capt+emheath+trnctl+lclecho+modoff
  1743.     mov    yflags,al        ; mask for allowable and save
  1744.     mov    al,[bx].prt
  1745.     mov    portno,al        ; update port number
  1746.     mov    ax,[bx].captr
  1747.     mov    captrtn,ax        ; buffer capture routine
  1748.     mov    parmsk,0ffh        ; parity mask, assume parity = None
  1749.     cmp    [bx].parity,parnon    ; is parity None?
  1750.     je    argini1            ; e = yes, keep all 8 bits
  1751.     mov    parmsk,07fh        ; else keep lower 7 bits
  1752. argini1:ret
  1753. argini    endp
  1754.  
  1755. term    proc    near            ; terminal mode entry point
  1756.     mov    bx,portval        ; port data structure address
  1757.     mov    bx,[bx].flowc        ; get flow control chars (bl=xoff)
  1758.     mov    flowon,bh
  1759.     mov    flowoff,bl        ; save for later
  1760.     mov    oldsp,sp        ; remember stack for i/o failure,
  1761.     mov    argadr,ax        ; save argument ptr
  1762.     call    argini            ; init options from arg address
  1763.     call    scrmod            ; get screen mode now
  1764.     mov    ah,crt_cols        ; screen width
  1765.     cmp    ah,dos_cols        ; has it changed?
  1766.     je    term1            ; e = no
  1767.     mov    dos_cols,ah        ; remember for exiting Connect mode
  1768.     mov    vtinited,0        ; need to reset emulator too
  1769.     and    vtemu.vtflgop,not deccol; set emulator to 80 column mode
  1770.     and    vtemu.vtflgst,not deccol
  1771.     cmp    crt_cols,80        ; narrow width now?
  1772.     jbe    term1            ; be = yes
  1773.     or    vtemu.vtflgop,deccol    ; set emulator to 132 column mode
  1774.     or    vtemu.vtflgst,deccol
  1775. term1:    mov    ax,100h            ; assume 80 column mode, no-renter
  1776.     test    vtemu.vtflgop,deccol    ; supposed to be in 80 col?
  1777.     jz    term2            ; z = yes
  1778.     inc    al            ; say want 132 cols
  1779. term2:    call    chgdsp            ; set to 80/132 columns
  1780.     call    scrmod            ; update emulator screen dimensions
  1781.     cmp    crt_cols,80        ; 80 cols now?
  1782.     ja    term2a            ; a = no
  1783.     and    vtemu.vtflgop,not deccol; tell emulator 80 column mode
  1784.     and    vtemu.vtflgst,not deccol
  1785.     jmp    short term3
  1786. term2a:    or    vtemu.vtflgop,deccol    ; tell emulator 132 column mode
  1787.     or    vtemu.vtflgst,deccol
  1788. term3:    call    scrini            ; init screen stuff
  1789.     or    kbcodes,80h        ; set need-to-init flg for kbd xtlator
  1790.  
  1791.     mov    fairprn,0        ; set printer buffer flush counter
  1792. lp:    call    prtchr            ; char at port?
  1793.     jnc    short lpinp        ; nc = yes, go handle
  1794.     push    bx
  1795.     mov    bx,portval        ; port structure address
  1796.     cmp    [bx].portrdy,0        ; is port ready for business?
  1797.     pop    bx
  1798.     jne    lpkbd            ; ne = ready
  1799.     jmp    endcon            ; end the communications now
  1800. lpkbd:    mov    fairness,0        ; say kbd was examined
  1801.     call    dvpause            ; tell DESQview we are not busy
  1802.     inc    fairprn            ; inc printer dump counter
  1803.     cmp    fairprn,1000        ; been here enough times now?
  1804.     jb    lpkbd1            ; b = no
  1805.     call    pntflsh            ; flush printer buffer
  1806.     jnc    lpkbd0            ; nc = success
  1807.     call    pntdead            ; call bad printer notifier
  1808. lpkbd0:    mov    fairprn,0        ; reset for next time
  1809. lpkbd1:    call    keybd            ; call keyboard translator in msu
  1810.     jnc    lp            ; nc = no char or have processed it
  1811.     jmp    short quit        ; carry set = quit connect mode
  1812. lpinp:    and    al,parmsk        ; apply 8/7 bit parity mask
  1813.     call    outtty            ; print on terminal
  1814.     inc    fairness        ; say read port but not kbd, again
  1815.     cmp    fairness,100        ; this many port reads before kbd?
  1816.     jb    lp            ; b = no, read port again
  1817.     jmp    short lpkbd        ; yes, let user have a chance too
  1818.  
  1819. quit:    mov    ah,scbattr        ; current emulator attributes
  1820.     mov    savattr,ah        ; save them here
  1821.     call    pntflsh            ; flush printer buffer
  1822.     call    tekend            ; cleanup Tektronix mode [bjh]
  1823.     call    getpos            ; get cursor position into dx
  1824.     mov    cursor,dx        ; save position
  1825.     mov    al,1
  1826.     call    csrtype            ; turn on underline cursor
  1827.     cmp    flags.vtflg,0        ; terminal type of none?
  1828.     je    quit1            ; e = yes
  1829.     cmp    flags.modflg,2        ; is modeline owned by remote host?
  1830.     je    quit1            ; e = yes
  1831.     call    clrmod            ; clear it before storing screen
  1832. quit1:    call    savescr            ; save screen
  1833.     mov    ah,dosattr        ; attributes at init time
  1834.     mov    scbattr,ah        ; background = original state
  1835.     call    clrmod            ; clear mode line with old attributes
  1836.     mov    ax,100h            ; assume using 80 col screen
  1837.     cmp    dos_cols,80        ; startup screen width
  1838.     jbe    quit1a            ; be = assume 80 columns
  1839.     inc    al            ; say do 132 columns
  1840. quit1a:    call    chgdsp            ; reset display width to startup
  1841.     call    scrmod            ; update size info
  1842.                     ; for ega in non-standard # lines
  1843.     cmp    ega_mode,0        ; ega board active?
  1844.     je    quit2            ; e = no
  1845.     cmp    byte ptr low_rgt+1,23    ; is screen standard length?
  1846.     je    quit2            ; e = yes, so regular cursor set is ok
  1847.     push    es            ; turn off ega cursor emulation
  1848.     mov    ax,40h            ; byte 40:87H is ega Info byte
  1849.     mov    es,ax
  1850.     push    es:[87h]        ; save info byte around call
  1851.     or    byte ptr es:[87h],1    ; set emulation off (low bit = 1)
  1852.     mov    cx,lincur        ; cursor shape to set
  1853.     mov    ah,1            ; set the shape
  1854.     int    screen            ;   back to starting value
  1855.     pop    es:[87h]        ; recover original Info byte
  1856.     pop    es            ; and our work reg
  1857.     jmp    short quit3        ; skip regular mode cursor setting
  1858. quit2:                    ; for regular sized screen
  1859.     mov    cx,lincur        ; cursor type at startup
  1860.     mov    ah,1
  1861.     int    screen            ; restore cursor type
  1862. quit3:    mov    dh,byte ptr low_rgt+1    ; bottom line
  1863.     inc    dh            ; status line position
  1864.     xor    dl,dl            ; left most column
  1865.     call    setpos            ; set cursor position
  1866.     mov    al,yflags
  1867.     and    al,not lclecho        ; don't copy host's echo flag
  1868.     mov    bx,argadr
  1869.     mov    ah,[bx].flgs        ; get user's flag settings
  1870.     and    ah,lclecho        ; clear all but local echo bit
  1871.     or    [bx].flgs,al        ; update flags in arg block
  1872.     call    dvpause            ; tell DESQview we are not busy
  1873.     ret
  1874. term    endp
  1875.  
  1876. ; put the character in al to the screen
  1877. outtty    proc    near
  1878.     test    flags.remflg,d8bit    ; keep 8 bits for displays?
  1879.     jnz    outtt1            ; nz = yes, 8 bits if possible
  1880.     and    al,7fh            ; remove high bit
  1881. outtt1:    cmp    flags.vtflg,0        ; emulating a terminal?
  1882.     je    outnp10            ; e = no
  1883.     cmp    vtroll,0        ; auto roll back allowed?
  1884.     je    outem1            ; e = no, leave screen as is
  1885.     cmp    tekflg,0        ; Tek mode active?
  1886.     jne    outem1            ; ne = yes, skip screen rolling
  1887.     cmp    flags.vtflg,tttek    ; doing Tektronix emulation?
  1888.     je    outem2            ; e = yes, use Tek emulator
  1889.     push    ax            ; (BDT) save this for a tad
  1890.     mov    ax,linec        ; (BDT) are we at the buffer end?
  1891.     cmp    ax,lcnt            ; (BDT)  ...
  1892.     pop    ax            ; (BDT) restore the register
  1893.         je      outem1            ; (BDT) e = yes
  1894.     push    ax            ; (BDT) save AX again
  1895.         call    endwnd                  ; (BDT) restore screen [dlk]
  1896.     pop    ax            ; (BDT) restore the register
  1897. outem1:    cmp    flags.vtflg,tttek    ; doing Tektronix emulation?
  1898.     je    outem2            ; e = yes, use Tek emulator
  1899.     cmp    tekflg,0        ; Tek submode active for input?
  1900.     jne    outem2            ; ne = yes, use Tek emulator
  1901.     jmp    anstty            ; call terminal emulator routine & ret
  1902. outem2:    call    tekemu            ; use Tek emulator and return
  1903.     ret
  1904.                          ; use DOS for screen output
  1905. outnp10:test    flags.remflg,d8bit    ; keep 8 bits for displays?
  1906.     jnz    outnp9            ; nz = yes, 8 bits if possible
  1907.     and    al,7fh            ; remove high bit
  1908. outnp9:    cmp    rxtable+256,0        ; translation turned off?
  1909.     je    outnp7            ; e = yes, no translation
  1910.     push    bx
  1911.     mov    bx,offset rxtable    ; address of translate table
  1912.     xlatb                ; new char is in al
  1913.     pop    bx
  1914. outnp7:    test    anspflg,prtscr        ; should we be printing?
  1915.     jz    outnp8            ; no, keep going
  1916.     call    pntchr            ; queue char for printer
  1917.     jnc    outnp8            ; nc = successful print
  1918.     push    ax
  1919.     call    vtbell            ; else make a noise and
  1920.     call    trnprs            ;  turn off printing
  1921.     pop    ax
  1922. outnp8:    test    yflags,capt        ; capturing output?
  1923.     jz    outnp6            ; no, forget this part
  1924.     push    ax            ; save char
  1925.     call    captrtn            ; give it captured character
  1926.     pop    ax            ; restore character and keep going
  1927. outnp6:    test    yflags,trnctl        ; debug? if so use Bios tty mode
  1928.     jz    outnp4            ; z = no
  1929.     mov    ah,conout        ; DOS screen write
  1930.     cmp    al,7fh            ; Ascii Del char or greater?
  1931.     jb    outnp1            ; b = no
  1932.     je    outnp0            ; e = Del char
  1933.     push    ax            ; save the char
  1934.     mov    dl,7eh            ; output a tilde for 8th bit
  1935.     int    dos
  1936.     pop    ax            ; restore char
  1937.     and    al,7fh            ; strip high bit
  1938. outnp0:    cmp    al,7fh            ; is char now a DEL?
  1939.     jne    outnp1            ; ne = no
  1940.     and    al,3fH            ; strip next highest bit (Del --> '?')
  1941.     jmp    outnp2            ; send, preceded by caret
  1942. outnp1:    cmp    al,' '            ; control char?
  1943.     jae    outnp3            ; ae = no
  1944.     add    al,'A'-1        ; make visible
  1945. outnp2:    push    ax            ; save char
  1946.     mov    dl,5eh            ; caret
  1947.     int    dos            ; display it
  1948.     pop    ax            ; recover the non-printable char
  1949. outnp3:    push    ax
  1950.     mov    dl,al
  1951.     int    dos
  1952.     pop    ax
  1953.     ret
  1954. outnp4:    cmp    al,bell            ; bell (Control G)?
  1955.     jne    outnp5            ; ne = no
  1956.     jmp    vtbell            ; use short beep, avoid char loss
  1957. outnp5:    mov    dl,al            ; write without intervention
  1958.     mov    ah,conout
  1959.     int    dos            ; else let dos display char
  1960.     ret
  1961. outtty    endp
  1962.      
  1963. ;[IU2] Here to output an unsigned 8-bit number (in al) to the port
  1964. ; Used by terminal emulator escape sequence output.
  1965.      
  1966. prtnout proc    near
  1967.     mov    bl,10            ; Output in base 10
  1968.     jmp    prtno2            ; Ensure at least a zero
  1969.      
  1970. prtno1: or    al,al
  1971.     jnz    prtno2            ; nz = yes, do more digits
  1972.     ret                ; no, return from recursive call
  1973. prtno2: xor    ah,ah            ; clear previous remainder
  1974.     div    bl            ; divide off a digit
  1975.     push    ax            ; push remainder (in ah) on stack
  1976.     call    prtno1            ; recurse
  1977.     pop    ax            ; pop off a digit
  1978.     add    ah,'0'            ; make it ASCII
  1979.     mov    al,ah            ; send to port, in ah
  1980.     call    outprt
  1981.     jc    prtno3            ; failure, end connection
  1982.     ret
  1983. prtno3:    jmp    endcon
  1984. prtnout endp
  1985.  
  1986. ; send the character in al out to the serial port; handle echoing.
  1987. ; Can send an 8 bit char while displaying only 7 bits locally.
  1988. outprt    proc    near
  1989.     mov    ah,1            ; say local echo is permitted
  1990.     jmp    short outprt0
  1991. prtbout:xor    ah,ah            ; no local echo
  1992.  
  1993. outprt0:test    al,80h            ; high bit set?
  1994.     jz    outpr2            ; z = no
  1995.     cmp    al,9fh            ; above C1 area?
  1996.     ja    outpr2            ; a = yes
  1997.     test    vtemu.vtflgop,vscntl    ; doing 8-bit controls?
  1998.     jz    outprt5            ; z = no, send 7-bit control seq
  1999.     cmp    parmsk,7fh        ; using parity?
  2000.     jne    outpr2            ; ne = no
  2001. outprt5:cmp    al,0a0h            ; in GR?
  2002.     ja    outpr1            ; a = yes, else C1
  2003.     push    ax            ; save char
  2004.     mov    al,Escape        ; C1 as ESCAPE <char-40h>
  2005.     call    outpr2            ; send ESCAPE
  2006.     pop    ax            ; recover char
  2007.     sub    al,40h            ; strip high bit, relocate code
  2008.     jmp    short outpr2        ; send the char
  2009. outpr1:    push    ax            ; save char
  2010.     mov    al,Escape        ; send as ESC N  char & 7fh
  2011.     call    outpr2            ; ESC N is Single Shift 2
  2012.     mov    al,'N'
  2013.     call    outpr2
  2014.     pop    ax            ; recover char
  2015.     and    al,not 80h        ; strip high bit
  2016.     
  2017. outpr2:    or    ah,ah            ; local echo permitted?
  2018.     jz    outpr3            ; z = no
  2019.     test    yflags,lclecho        ; echoing?
  2020.     jz    outpr3            ; z = no, forget it
  2021.     push    ax            ; save char
  2022.     call    outtty            ; display it
  2023.     pop    ax            ; restore
  2024. outpr3:    mov    ah,al            ; this is where outchr expects it
  2025.     call    outchr            ; output to the port
  2026.     jc    outpr4            ; c = failure
  2027.     ret
  2028. outpr4:    jmp    endcon            ; failure, end connection
  2029. outprt    endp
  2030.  
  2031. ; Jump here to exit Connect mode and execute macros 'TERMINALR' (vtrmac) or
  2032. ; 'TERMINALS' (vtsmac). Does nothing if macro does not exist.
  2033. ; Preserves registers except ax. Returns to TELNET caller with 'C' in kbdflg.
  2034. vtrmac    proc    near            ; RESET macro
  2035.     mov    vtmacname,offset vtrname ; select macro name
  2036.     mov    vtmaclen,vtrlen        ; and its length
  2037.     call    dword ptr vtmacroptr    ; FAR pointer, finish in common code
  2038.     ret
  2039. vtrmac    endp
  2040.  
  2041. vtsmac    proc    near            ; SET macro
  2042.     mov    vtmacname,offset vtsname
  2043.     mov    vtmaclen,vtslen
  2044.     call    dword ptr vtmacroptr    ; FAR pointer
  2045.     ret
  2046. vtsmac    endp
  2047.  
  2048. ; Invoked by keyboard translator when an unknown keyboard verb is used as
  2049. ; a string definition, such as {\ktest}. Enter with vtmacname pointing to
  2050. ; uppercased verb name, asciiz, and vtmaclen set to its length.
  2051. extmacro proc    near
  2052.     call    dword ptr vtmacroptr    ; FAR pointer
  2053.     ret
  2054. extmacro endp
  2055.  
  2056. ; Same as TERMINALR/S except invokes macro PRODUCT with variables \%1..\%9
  2057. ; defined as the ascii renditions of the control sequence numeric paramters
  2058. ; param[0]..param[8], and sets script ARGC item to one greater than this.
  2059.  
  2060. product    proc    near
  2061.     call    dword ptr productptr    ; FAR pointer
  2062.     ret
  2063. product    endp
  2064.  
  2065.                 ; support for vtmacro and fproduct
  2066. fdec2di    proc    far
  2067.     call    dec2di
  2068.     ret
  2069. fdec2di    endp
  2070. code    ends
  2071.  
  2072. code1    segment
  2073.     assume    cs:code1
  2074.  
  2075. fproduct proc    far
  2076.     push    si
  2077.     push    di
  2078.     push    es
  2079.     mov    ax,ds
  2080.     mov    es,ax
  2081.     mov    di,offset rdbuf+2    ; macro def buffer starts here
  2082.     mov    si,offset prodname    ; pointer to macro name
  2083.     mov    cx,vtplen        ; length of macro name
  2084.     cld
  2085.     rep    movsb            ; copy to rdbuf+2
  2086.     mov    byte ptr [di],0        ; null terminator
  2087.     mov    cx,nparam        ; number of parameters
  2088.     cmp    cx,9            ; more than 9?
  2089.     jle    produc1            ; le = no
  2090.     mov    cx,9            ; limit to 9
  2091. produc1:jcxz    produc3            ; z = none
  2092.     xor    bx,bx            ; parameter subscript
  2093. produc2:push    bx
  2094.     push    cx
  2095.     mov    al,' '            ; and a space separator
  2096.     stosb
  2097.     shl    bx,1            ; address words
  2098.     mov    ax,param[bx]        ; get parameter to use as definition
  2099.     call    fdec2di            ; convert numerics to ascii string
  2100.     pop    cx
  2101.     pop    bx
  2102.     inc    bx
  2103.     loop    produc2
  2104. produc3:xor    al,al            ; safety terminator
  2105.     mov    [di],al            ; don't count in length
  2106.     mov    ax,di
  2107.     sub    ax,offset rdbuf        ; compute length
  2108.     mov    vtmaclen,ax        ; pass along to vtmacro
  2109.     mov    vtmacname,offset rdbuf+2 ; say this is our macro text ptr
  2110.     pop    si
  2111.     pop    di
  2112.     pop    es
  2113.     jmp    short vtmacro
  2114. fproduct endp
  2115.  
  2116. ;
  2117. ; Reference    Macro structure for    db    number of entries (mac names)
  2118. ;  is file     table mcctab       |->    dw    length of macroname
  2119. ;  mssset.asm        each entry |->     db    'macroname'
  2120. ;  where these               |->    dw    segment:0 of definition string
  2121. ;  are stored.                      (offset part is always 0)    
  2122. ;        Definition string in     db    length of <string with null>
  2123. ;         buffer macbuf          db    'string with trailing null'
  2124. ;
  2125. vtmacro    proc    far            ; common code for macros vtsmac,vtrmac
  2126.     push    bx            ; and Product
  2127.     push    cx
  2128.     push    si
  2129.     push    di
  2130.     push    es
  2131.     mov    ax,ds
  2132.     mov    es,ax
  2133.     mov    di,offset rdbuf+2    ; macro def buffer starts here
  2134.     mov    si,vtmacname        ; pointer to macro name
  2135.     mov    cx,vtmaclen        ; length of macro name<sp/null>text
  2136.     mov    [di-2],cx        ; counted string field
  2137.     cld
  2138.     rep    movsb            ; copy to rdbuf
  2139.     mov    byte ptr [di],0        ; null terminator
  2140.     mov    si,offset rdbuf+2    ; look for name-text separator
  2141.     mov    cx,vtmaclen
  2142. vtmac1:    lodsb
  2143.     cmp    al,' '            ; space separator?
  2144.     je    vtmac1a            ; e = yes, stop here
  2145.     or    al,al            ; null terminator?
  2146.     jz    vtmac1a            ; e = yes, stop here
  2147.     loop    vtmac1
  2148.     inc    si            ; to do null length correctly
  2149. vtmac1a:sub    si,offset rdbuf+2+1    ; compute length of macro name
  2150.     mov    cx,si
  2151.     mov    vtmaclen,cx        ; save a macro name length
  2152.                     ; check for existence of macro
  2153.     mov    bx,offset mcctab    ; table of macro names
  2154.     mov    cl,[bx]            ; number of names in table
  2155.     xor    ch,ch
  2156.     jcxz    vtmacx            ; z = empty table, do nothing
  2157.     inc    bx            ; point to length of first name
  2158. vtmac2:    mov    ax,[bx]            ; length of this name
  2159.     cmp    ax,vtmaclen        ; length same as desired keyword?
  2160.     jne    vtmac3            ; ne = no, search again
  2161.     mov    si,bx
  2162.     add    si,2            ; point at first char of name
  2163.     push    cx            ; save name counter
  2164.     push    di            ; save reg
  2165.     mov    cx,vtmaclen        ; length of name
  2166.     mov    di,vtmacname        ; point at desired macro name
  2167.     push    es            ; save reg
  2168.     push    ds
  2169.     pop    es            ; make es use data segment
  2170.     cld
  2171.     repe    cmpsb            ; match strings
  2172.     pop    es            ; need current si below
  2173.     pop    cx
  2174.     pop    di            ; recover saved regs
  2175.     je    vtmac4            ; e = matched
  2176. vtmac3:    add    bx,ax            ; step to next name, add name length
  2177.     add    bx,4            ; + count and def word ptr
  2178.     loop    vtmac2            ; try next name
  2179. vtmacx:    pop    es
  2180.     pop    di
  2181.     pop    si            ; no macro, return to Connect mode
  2182.     pop    cx
  2183.     pop    bx
  2184.     ret
  2185.  
  2186. vtmac4:    cmp    taklev,maxtak        ; room in Take level?
  2187.     jge    vtmacx            ; ge = no, exit with no action
  2188.     inc    taklev            ; increment take level
  2189.     add    takadr,size takinfo    ; make a new Take entry/macro
  2190.     mov    bx,takadr        ; point to current macro structure
  2191.     mov    ax,ds            ; segment of rdbuf
  2192.     mov    [bx].takbuf,ax        ; segment of definition string struc
  2193.     mov    cx,word ptr rdbuf    ; length of count + string
  2194.     mov    [bx].takcnt,cx        ; number of chars in definition
  2195.     mov    [bx].takargc,0        ; our argument count
  2196.     mov    [bx].takptr,offset rdbuf+2 ; where to read next command char
  2197.     mov    [bx].taktyp,0ffh    ; flag as a macro
  2198.     pop    es
  2199.     pop    di
  2200.     pop    si
  2201.     pop    cx
  2202.     pop    bx
  2203.     jmp    dword ptr endconptr    ; exit Connect mode
  2204. vtmacro    endp
  2205. code1    ends
  2206.  
  2207. code    segment
  2208.     assume    cs:code
  2209.  
  2210. ; Error recovery routine used when outchr reports unable to send character
  2211. ;  or when vtmacro requests exiting Connect mode.
  2212. ; Exit Connect mode cleanly, despite layers of intermediate calls.
  2213. endcon    proc    near
  2214.     mov    kbdflg,'C'        ; report 'C' to TERM's caller
  2215.     mov    sp,oldsp        ; recover startup stack pointer
  2216.                     ; TERM caller's return address is now
  2217.                     ; on the top of stack. A longjmp.
  2218.     jmp    quit            ; exit Connect mode cleanly
  2219. endcon    endp
  2220.  
  2221. ;;; Action routines (verbs) for keyboard translator KEYBD in msuibm.
  2222. ; These are invoked by a jump instruction. Return carry clear for normal
  2223. ; processing, return carry set for invoking Quit (kbdflg has transfer char).
  2224. uparrw:    mov    al,'A'            ; cursor keys
  2225.     jmp    short comarr
  2226. dnarrw:    mov    al,'B'
  2227.     jmp    short comarr
  2228. rtarr:    mov    al,'C'
  2229.     test    vtemu.vtflgop,vswdir    ; writing left to right?
  2230.     jz    comarr            ; z = yes
  2231.     mov    al,'D'            ; reverse sense of keys
  2232.     jmp    short comarr
  2233. lfarr:    mov    al,'D'
  2234.     test    vtemu.vtflgop,vswdir    ; writing left to right?
  2235.     jz    comarr            ; z = yes
  2236.     mov    al,'C'            ; reverse sense of keys
  2237. comarr:    push    ax            ; save final char
  2238.     mov    ttyact,0        ; network, group chars for packet
  2239.     test    vtemu.vtflgop,decanm    ; ANSI mode?
  2240.     jz    comar2            ; z = no
  2241.     mov    al,CSI            ; CSI character
  2242.     test    vtemu.vtflgop,decckm    ; cursor key mode reset?
  2243.     jz    comar1            ; z = yes
  2244.     mov    al,SS3            ; SS3 character
  2245. comar1:    call    outprt            ; send in 7 or 8 bit form, with echo
  2246.     jmp    short comar3
  2247.  
  2248. comar2:    mov    al,escape        ; do Heath/VT52 mode "ESC char"
  2249.     call    outprt
  2250. comar3: pop    ax            ; recover final char
  2251.     mov    ttyact,1        ; network, restore tty active flag
  2252.     call    outprt
  2253.     ret
  2254.  
  2255. pf1:    mov    al,'P'            ; keypad function keys PF1-4
  2256.     jmp    short compf
  2257. pf2:    mov    al,'Q'
  2258.     jmp    short compf
  2259. pf3:    mov    al,'R'
  2260.     jmp    short compf
  2261. pf4:    mov    al,'S'
  2262. compf:    push    ax            ; save final char
  2263.     mov    ttyact,0        ; network, group chars for packet
  2264.     test    vtemu.vtflgop,decanm    ; ansi mode?
  2265.     jz    short compf1        ; z = no
  2266.     mov    al,SS3
  2267.     call    outprt            ; send 7 or 8 bit version
  2268.     jmp    short compf2
  2269. compf1:    mov    al,escape        ; output ESC
  2270.     call    outprt
  2271. compf2: pop    ax            ; get the saved char
  2272.     mov    ttyact,1        ; network, restore tty active flag
  2273.     call    outprt
  2274.     ret
  2275.  
  2276. kp0:    mov    al,'p'            ; keypad numeric keys
  2277.     jmp    short comkp
  2278. kp1:    mov    al,'q'
  2279.     jmp    short comkp
  2280. kp2:    mov    al,'r'
  2281.     jmp    short comkp
  2282. kp3:    mov    al,'s'
  2283.     jmp    short comkp
  2284. kp4:    mov    al,'t'
  2285.     jmp    short comkp
  2286. kp5:    mov    al,'u'
  2287.     jmp    short comkp
  2288. kp6:    mov    al,'v'
  2289.     jmp    short comkp
  2290. kp7:    mov    al,'w'
  2291.     jmp    short comkp
  2292. kp8:    mov    al,'x'
  2293.     jmp    short comkp
  2294. kp9:    mov    al,'y'
  2295.     jmp    short comkp
  2296. kpminus:mov    al,'m'
  2297.     jmp    short comkp
  2298. kpcoma:    mov    al,'l'
  2299.     jmp    short comkp
  2300. kpenter:mov    al,'M'
  2301.     jmp    short comkp
  2302. kpdot:    mov    al,'n'
  2303. comkp:    test    vtemu.vtflgop,deckpam    ; keypad application mode active?
  2304.     jnz    comkp1            ; nz = yes, use escape sequences
  2305.     sub    al,40h            ; deduct offset to numeric symbols
  2306.     push    ax            ; save final char
  2307.     jmp    short comkp3        ; and send that single char
  2308. comkp1:    push    ax
  2309.     mov    ttyact,0        ; network, group chars for packet
  2310.     test    vtemu.vtflgop,decanm    ; ANSI mode?
  2311.     jz    comkp2            ; z = no
  2312.     mov    al,SS3            ; SS3 character
  2313.     call    outprt            ; send 7 or 8 bit version
  2314.     jmp    short comkp3
  2315. comkp2:    mov    al,escape        ; output "ESC ?"
  2316.     call    outprt
  2317.     mov    al,'?'
  2318.     call    outprt
  2319. comkp3:    pop    ax            ; recover final char
  2320.     mov    ttyact,1        ; network, restore tty active flag
  2321.     call    outprt            ; send it
  2322.     ret
  2323.  
  2324. klogon    proc    near            ; resume logging (if any)
  2325.     test    flags.capflg,logses    ; session logging enabled?
  2326.     jz    klogn            ; z = no, forget it
  2327.     push    bx
  2328.     mov    bx,argadr
  2329.     or    [bx].flgs,capt        ; turn on capture flag
  2330.     pop    bx
  2331.     or    yflags,capt        ; set local msy flag as well
  2332. klogn:    clc
  2333.     ret
  2334. klogon    endp
  2335.  
  2336. klogof    proc    near            ; suspend logging (if any)
  2337.     push    bx
  2338.     mov    bx,argadr
  2339.     and    [bx].flgs,not capt    ; stop capturing
  2340.     pop    bx
  2341.     and    yflags,not capt        ; reset local msy flag as well
  2342.     clc
  2343.     ret
  2344. klogof    endp
  2345.  
  2346. snull    proc    near            ; send a null byte
  2347.     xor    al,al            ; the null
  2348.     jmp    prtbout            ; send without logging and local echo
  2349. snull    endp
  2350.  
  2351. khold:    xor    holdscr,1        ; toggle Hold screen byte for msx
  2352.     call    kbhold            ; tell DEC LK250 the hold kbd state
  2353.     clc                ;  kbhold is in file msuibm.asm
  2354.     ret
  2355.  
  2356. ; DEC LK201 keyboard keys and "User Definable Keys" in VT3xx mode
  2357. decfind:mov    al,1            ; Find
  2358.     jmp    udkout
  2359. decinsert:mov    al,2            ; Insert
  2360.     jmp    udkout
  2361. decremove:mov    al,3            ; Remove
  2362.     jmp    udkout
  2363. decselect:mov    al,4            ; Select
  2364.     jmp    udkout
  2365. decprev:mov    al,5            ; Previous screen
  2366.     jmp    udkout
  2367. decnext:mov    al,6            ; Next screen
  2368.     jmp    udkout
  2369. decf6:    mov    al,17            ; key ident for DEC F6
  2370.     jmp    udkout            ; process it
  2371. decf7:    mov    al,18            ; key ident for DEC F7
  2372.     jmp    udkout            ; process it
  2373. decf8:    mov    al,19            ; key ident for DEC F8
  2374.     jmp    udkout            ; process it
  2375. decf9:    mov    al,20            ; key ident for DEC F9
  2376.     jmp    udkout            ; process it
  2377. decf10:    mov    al,21            ; key ident for DEC F10
  2378.     jmp    udkout            ; process it
  2379. decf11:    mov    al,23            ; key ident for DEC F11
  2380.     jmp    udkout            ; process it
  2381. decf12:    mov    al,24            ; key ident for DEC F12
  2382.     jmp    udkout            ; process it
  2383. decf13:    mov    al,25            ; key ident for DEC F13
  2384.     jmp    udkout            ; process it
  2385. decf14:    mov    al,26            ; key ident for DEC F14
  2386.     jmp    udkout            ; process it
  2387. dechelp:mov    al,28            ; key ident for DEC HELP
  2388.     jmp    udkout            ; process it
  2389. decdo:    mov    al,29            ; key ident for DEC DO
  2390.     jmp    udkout            ; process it
  2391. decf17:    mov    al,31            ; key ident for DEC F17
  2392.     jmp    udkout            ; process it
  2393. decf18:    mov    al,32            ; key ident for DEC F18
  2394.     jmp    udkout            ; process it
  2395. decf19:    mov    al,33            ; key ident for DEC F19
  2396.     jmp    udkout            ; process it
  2397. decf20:    mov    al,34            ; key ident for DEC F20
  2398.     jmp    udkout            ; process it
  2399.  
  2400. ; common worker to output contents of User Definable Key definition strings
  2401. ; Enter with al = key ident (17 - 34)
  2402. udkout    proc    near
  2403.     push    ax
  2404.     push    bx
  2405.     push    cx
  2406.     push    es
  2407.     test    flags.vtflg,ttvt320+ttvt220 ; VT320/VT220?
  2408.     jnz    udkout3            ; nz = yes, else use VT100/VT52 default
  2409.     test    flags.vtflg,tttek    ; Tek?
  2410.     jnz    udkout3            ; nz = yes, try this
  2411.     cmp    al,23            ; F11 sends ESC
  2412.     jne    udkou1a            ; ne = not F11
  2413.     mov    al,escape
  2414.     call    outprt
  2415.     jmp    udkoutx
  2416. udkou1a:cmp    al,24            ; F12 sends BS
  2417.     jne    udkou1b            ; ne = not F12
  2418.     mov    al,BS
  2419.     call    outprt
  2420.     jmp    udkoutx
  2421. udkou1b:cmp    al,25            ; F13 sends LF
  2422.     jne    udkou1c            ; ne = not F13, ignore
  2423.     mov    al,LF
  2424.     call    outprt
  2425. udkou1c:jmp    udkoutx
  2426.  
  2427. udkout3:mov    bl,al            ; VT3XX key ident, UDK style (17-34)
  2428.     cmp    al,6            ; is this the CSI 1-6 set?
  2429.     jbe    udkout4            ; be = yes, do separately
  2430.     sub    bl,17            ; minus starting offset of 17
  2431.     xor    bh,bh
  2432.     cmp    bl,17            ; out of range?
  2433.     ja    udkoutx            ; a = yes, ignore
  2434.     shl    bx,1            ; index words
  2435.     mov    bx,udkseg[bx]        ; segment of definition
  2436.     or    bx,bx            ; anything there?
  2437.     jz    udkout4            ; z = no, use DEC defaults below
  2438.     mov    es,bx            ; definition segment
  2439.     xor    bx,bx            ;  and offset
  2440.     mov    cl,es:[bx]        ; get string length byte
  2441.     xor    ch,ch            ; use cx as a counter
  2442.     jcxz    udkout4            ; z = empty, use defaults
  2443. udkou3a:inc    bx            ; es:bx is now the string text
  2444.     mov    al,es:[bx]        ; get a char
  2445.     push    bx
  2446.     push    cx
  2447.     push    es
  2448.     call    outprt            ; output
  2449.     pop    es
  2450.     pop    cx
  2451.     pop    bx
  2452.     loop    udkou3a
  2453.     jmp    short udkoutx        ; done
  2454.  
  2455. udkout4:push    ax            ; VT320, use default definitions
  2456.     mov    al,CSI            ; char to send
  2457.     call    outprt            ; send lead-in char in 7/8-bit form
  2458.     pop    ax
  2459.     call    prtnout            ; key ident (17-34) as ascii digits
  2460.     mov    al,7eh            ; tilde terminator
  2461.     call    outprt
  2462. udkoutx:pop    es
  2463.     pop    cx
  2464.     pop    bx
  2465.     pop    ax
  2466.     clc
  2467.     ret
  2468. udkout    endp
  2469.  
  2470. ; Set (define) the DEC "User Definable Keys". Inserts text definitions for
  2471. ; keyboard verbs \KdecF6 ...\KdecF14, \KdecHELP, \KdecDO, \KdecF17...\KdecF20.
  2472. ; Enter with the DCS definition string as key-number/hex-chars. UDK key number
  2473. ; is 17 for \KdecF6, et seq, the definition are pairs of hex digits converted
  2474. ; here to a single byte per pair. The DCS definition string is pointed at by
  2475. ; DS:SI, and the byte count is in CX.
  2476. ; Example:  17/54657374204636   means key \KdecF6 sends string "Test F6"
  2477. setudk    proc    near
  2478.     push    ax
  2479.     push    bx
  2480.     push    cx
  2481.     push    si
  2482.     push    di
  2483.     push    es
  2484.     cld
  2485.     lodsb                ; get key ident first byte
  2486.     sub    al,'0'            ; ascii to binary
  2487.     mul    ten            ; times 10
  2488.     xchg    ah,al            ; to ah
  2489.     lodsb                ; get key ident second byte
  2490.     sub    al,'0'            ; ascii to binary
  2491.     add    al,ah            ; plus high order part
  2492.     xor    ah,ah
  2493.     mov    bx,ax            ; key ident, 17 - 34
  2494.     lodsb                ; skip slash separator
  2495.     sub    cx,3            ; three less bytes in the string
  2496.     jge    setudk0            ; ge = had three or more bytes
  2497.     jmp    setudkx            ; else error
  2498. setudk0:sub    bx,17            ; remove key ident bias of 17
  2499.     cmp    bx,17            ; out of range?
  2500.     ja    setudkx            ; a = yes, ignore
  2501.     shl    bx,1            ; index words
  2502.     cmp    udkseg[bx],0        ; has a segment been allocated for it?
  2503.     je    setudk1            ; e = no
  2504.     mov    ax,udkseg[bx]        ; get segment to es
  2505.     mov    es,ax
  2506.     mov    ah,freemem        ; deallocate old memory block, es:0
  2507.     int    dos
  2508.     mov    udkseg[bx],0        ; clear table entry too
  2509. setudk1:and    cl,not 1        ; force an even number of inputs
  2510.     jcxz    setudkx            ; z = no definition, clear entry
  2511.     push    bx            ; save index BX
  2512.     mov    bx,cx            ; get string length
  2513.     shr    bx,1            ; two hex digits per final byte
  2514.     add    bx,15+1            ; round up plus length byte
  2515.     shr    bx,1            ; convert to paragraphs
  2516.     shr    bx,1
  2517.     shr    bx,1
  2518.     shr    bx,1
  2519.     mov    di,bx            ; remember request
  2520.     mov    ah,alloc        ; allocate BX paragraphs
  2521.     int    dos
  2522.     jc    setudkx            ; c = failure
  2523.     cmp    di,bx            ; requested vs allocated
  2524.     pop    bx            ; recover bx
  2525.     je    setudk2            ; e = enough
  2526.     mov    ah,freemem        ; return the memory, es is ptr
  2527.     int    dos
  2528.     jmp    short setudkx        ; exit failure
  2529.  
  2530. setudk2:mov    es,ax            ; segment of allocated memory
  2531.     mov    udkseg[bx],es        ; segment:0 of definition string
  2532.     xor    di,di
  2533.     cld
  2534.     mov    al,cl            ; length of string
  2535.     shr    al,1            ; two hex bytes per stored byte
  2536.     xor    ch,ch
  2537.     stosb                ; store length byte
  2538.     jcxz    setudkx            ; z = empty string
  2539. setukd3:lodsb                ; get first hex digit
  2540.     dec    cx            ; adjust count remaining
  2541.     or    al,20h            ; to lower case
  2542.     cmp    al,'9'            ; digit?
  2543.     jbe    setudk4            ; be = yes
  2544.     sub    al,'a'-'9'-10        ; hex letter to column three
  2545. setudk4:sub    al,'0'            ; ascii to binary
  2546.     shl    al,1            ; times 16
  2547.     shl    al,1
  2548.     shl    al,1
  2549.     shl    al,1
  2550.     mov    ah,al            ; save in ah
  2551.     lodsb                ; get second hex digit
  2552.     or    al,20h            ; to lower case
  2553.     cmp    al,'9'            ; digit?
  2554.     jbe    setudk5            ; be = yes
  2555.     sub    al,'a'-'9'-10        ; hex letter to column three
  2556. setudk5:sub    al,'0'            ; ascii to binary
  2557.     add    al,ah            ; join both parts
  2558.     stosb                ; store final byte
  2559.     loop    setukd3
  2560. setudkx:pop    es
  2561.     pop    di
  2562.     pop    si
  2563.     pop    cx
  2564.     pop    bx
  2565.     pop    ax
  2566.     clc
  2567.     ret
  2568. setudk    endp
  2569.  
  2570. ; Clear all User Definable Keys, deallocate memory for their definitions
  2571. udkclear proc    near
  2572.     push    ax
  2573.     push    bx
  2574.     push    cx
  2575.     push    es
  2576.     mov    cx,17            ; 17 entries
  2577.     xor    bx,bx
  2578. udkcle1:mov    ax,udkseg[bx]        ; segment of definition
  2579.     or    ax,ax            ; segment defined?
  2580.     jz    udkcle2            ; z = no, try next key
  2581.     mov    es,ax
  2582.     mov    udkseg[bx],0        ; clear the entry
  2583.     mov    ah,freemem        ; release the memory
  2584.     int    dos
  2585. udkcle2:add    bx,2            ; word index
  2586.     loop    udkcle1            ; do all
  2587.     pop    es
  2588.     pop    cx
  2589.     pop    bx
  2590.     pop    ax
  2591.     clc
  2592.     ret
  2593. udkclear endp
  2594.  
  2595.                     ; general character out for emulator
  2596. chrout:    cmp    flags.vtflg,0        ; emulating?
  2597.     je    chrou5            ; e = no
  2598.     call    anskbi            ; say we had keyboard input
  2599.     cmp    al,cr            ; CR?
  2600.     jne    chrou5            ; ne = no, just output it and return
  2601.     test    vtemu.vtflgop,anslnm    ; ANSI new-line mode set?
  2602.     jz    chrou5            ; z = no, just send the cr
  2603.     cmp    dupflg,0        ; full duplex?
  2604.     je    chrou4            ; e = yes
  2605.     cmp    al,trans.seol        ; End of Line char?
  2606.     jne    chrou5            ; ne = no
  2607. chrou4:    mov    ah,trans.seol        ; save eol char
  2608.     push    ax            ; save on stack
  2609.     mov    trans.seol,lf        ; make LF the eol char
  2610.     call    outprt            ; output a carriage-return
  2611.     mov    al,lf            ; followed by a line feed
  2612.     call    outprt            ; send the LF
  2613.     pop    ax
  2614.     mov    trans.seol,ah        ; restore eol char
  2615.     ret
  2616. chrou5:    jmp    outprt
  2617.  
  2618.                     ; these commands invoke Quit
  2619. cdos:    mov    al,'P'            ; Push to DOS
  2620.     jmp    short cmdcom
  2621. cstatus:mov    al,'S'            ; Status
  2622.     jmp    short cmdcom
  2623. cquit:    mov    al,'C'            ; Exit Connect mode
  2624.     jmp    short cmdcom
  2625. cquery:    mov    al,'?'            ; Help
  2626.     jmp    short cmdcom
  2627. chang:    mov    al,'H'            ; Hangup, drop DTR & RTS
  2628.     jmp    short cmdcom
  2629. cmdcom:    mov    kbdflg,al        ; pass char to msster.asm via kbdflg
  2630.     stc                ; signal that Quit is needed
  2631.     ret
  2632.                        ; Screen dump entry from keyboad xlat
  2633. dmpscn    proc    near            ; dump screen to file
  2634.     cmp    flags.vtflg,tttek    ; doing Tektronix emulation?
  2635.     je    dmpscn2            ; e = yes, use Tek emulator
  2636.     test    tekflg,1        ; emulation a Tektronix?
  2637.     jz    dmpscn1            ; z = no
  2638. dmpscn2:call    tekdmp            ; near-call Tek screen dump utility
  2639.     clc
  2640.     ret
  2641. dmpscn1:call    savescr            ; save screen to buffer
  2642.     call    dumpscr            ; do buffer to file
  2643.     clc                ; do not exit Connect mode
  2644.     ret
  2645. dmpscn    endp
  2646.  
  2647.      
  2648. ;[IU2] Routine to toggle VT100/VT52/Heath-19 modes in VT100 emulator.
  2649.      
  2650. vtans52 proc    near
  2651.     cmp    flags.vtflg,0        ; emulating?
  2652.     je    vtans5            ; e = no
  2653.     call    ans52t            ; call MSZ toggle-it routine
  2654.     clc                ; clear c bit so don't exit Connect
  2655. vtans5:    ret
  2656. vtans52 endp
  2657.                     ; Toggle Mode Line
  2658. trnmod    proc    near
  2659.     cmp    flags.modflg,1        ; mode line enabled and owned by us?
  2660.     jne    trnm1            ; ne = no, don't touch it
  2661.     cmp    flags.vtflg,tttek    ; Tek mode?
  2662.     je    trnm3            ; e = yes
  2663.     cmp    tekflg,0        ; Tek submode?
  2664.     jne    trnm3            ; ne = yes, no mode line changes
  2665.     test    yflags,modoff        ; mode line already off?
  2666.     jnz    trnm2            ; nz = yes, go turn on
  2667.     or    yflags,modoff        ; say modeline is toggled off
  2668.     call    clrmod            ; clear mode line
  2669. trnm1:    clc                ; clear c bit so don't exit Connect
  2670.     ret
  2671. trnm2:    cmp    flags.vtflg,0        ; emulating a terminal?
  2672.     jne    trnm3            ; ne = yes
  2673.     push    dx            ; scroll screen to save bottom line
  2674.     mov    ah,prstr        ; for terminal type none
  2675.     mov    dx,offset crlf
  2676.     int    dos
  2677.     pop    dx
  2678. trnm3:    call    modlin            ; turn on modeline
  2679.     and    yflags,not modoff    ; say modeline is not toggled off
  2680.     clc
  2681.     ret
  2682. trnmod    endp
  2683.  
  2684. modlin    proc    near            ; turn on mode line
  2685.     push    es
  2686.     mov    ax,ds
  2687.     mov    es,ax
  2688.     mov    si,offset modmaster    ; master template
  2689.     mov    di,offset modbuf    ; working copy
  2690.     cld
  2691. modl20:    lodsb
  2692.     stosb
  2693.     cmp    al,'$'            ; at end?
  2694.     jne    modl20            ; ne = no
  2695.     mov    al,trans.escchr        ; Connect mode escape character
  2696.     mov    modbuf.m_echr,' '    ; first char is initial space
  2697.     mov    modbuf.m_hlp,' '    ; goes here too
  2698.     cmp    al,32            ; printable?
  2699.     jnb    modl1            ; yes, keep going
  2700.     add    al,40h            ; made printable
  2701.     mov    modbuf.m_echr,5eh    ; caret, note control char
  2702.     mov    modbuf.m_hlp,5eh
  2703. modl1:    mov    modbuf.m_echr+1,al    ; fill in character
  2704.     mov    modbuf.m_hlp+1,al
  2705.     mov    bx,argadr        ; get argument block
  2706.     mov    al,[bx].baudb        ; get baud bits
  2707.     mov    si,offset unkbaud    ; assume unknown baud
  2708.     mov    cx,size m_baud        ; length of baud space
  2709.     cmp    al,baudnsiz        ; beyond end of table?
  2710.     jnb    modl2            ; nb = yes, use default
  2711.     mul    cl
  2712.     xor    ah,ah
  2713.     add    ax,offset baudn
  2714.     mov    si,ax
  2715. modl2:    mov    di,offset modbuf.m_baud
  2716.     cld
  2717.     rep    movsb            ; copy in baud rate
  2718.     mov    al,[bx].parity        ; get parity code
  2719.     shl    al,1            ; each is 4 bytes long
  2720.     shl    al,1
  2721.     xor    ah,ah
  2722.     add    ax,offset parnams    ; names of parity settings
  2723.     mov    si,ax
  2724.     mov    cx,4            ; each is 4 long
  2725.     mov    di,offset modbuf.m_par
  2726.     rep    movsb
  2727.     mov    si,offset remmsg    ; assume remote echoing
  2728.     test    yflags,lclecho        ; local echo on?
  2729.     jz    modl3            ; z = no
  2730.     mov    si,offset lclmsg    ; say echo is local
  2731. modl3:    mov    cx,3            ; size of on/off
  2732.     mov    di,offset modbuf.m_echo
  2733.     rep    movsb
  2734.     mov    al,portno        ; communications port
  2735.     cmp    al,' '            ; binary (non-printable)?
  2736.     jae    modl4            ; ae = no, ascii
  2737.     add    al,'0'            ; convert to ascii
  2738. modl4:    mov    modbuf.m_prt,al        ; fill in port number
  2739.     mov    al,portno
  2740.     cmp    repflg,0        ; REPLAY?
  2741.     je    modl5            ; e = no
  2742.     mov    si,offset repmsg    ; say "REPLAY"
  2743.     mov    cx,repmsgl        ; its length
  2744.     mov    di,offset modbuf.m_prt
  2745.     mov    al,' '            ; start with a space
  2746.     stosb
  2747.     mov    dx,12            ; space to be filled
  2748.     sub    dx,cx            ; amount we will use here
  2749.     rep    movsb            ; copy string
  2750.     mov    cx,dx
  2751.     rep    stosb            ; flesh out with spaces
  2752.     jmp    short modl10
  2753.  
  2754. modl5:    cmp    al,'4'            ; in networks material?
  2755.     jbe    modl10            ; be = no
  2756.     mov    bx,offset comptab    ; table of comms ports
  2757.     mov    cl,[bx]            ; number of entries
  2758.     xor    ch,ch
  2759.     inc    bx
  2760. modl6:    mov    dx,[bx]            ; length of this entry
  2761.     mov    si,bx
  2762.     add    si,2            ; points to entry text string
  2763.     add    si,dx            ; point to qualifier
  2764.     cmp    [si],al            ; our port?
  2765.     je    modl7            ; e = yes
  2766.     add    bx,[bx]            ; add text length
  2767.     add    bx,4            ; plus count and qualifier
  2768.     loop    modl6            ; next entry
  2769.     jmp    short modl10        ; no match, curious
  2770. modl7:    mov    si,bx            ; point at entry
  2771.     add    si,2            ; point at string
  2772.     mov    cx,[bx]            ; length of string
  2773.     mov    di,offset modbuf.m_prt
  2774.     mov    al,' '            ; start with a space
  2775.     stosb
  2776.     mov    dx,12            ; space to be filled
  2777.     sub    dx,cx            ; amount we will use here
  2778.     rep    movsb            ; copy string
  2779.     mov    cx,dx
  2780.     rep    stosb            ; flesh out with spaces
  2781. modl10:
  2782.     mov    cx,8            ; blank out terminal id field
  2783.     mov    si,offset mtty        ; assume no terminal emulation
  2784.     mov    di,offset modbuf.m_term ; destination
  2785.     rep    movsb            ; copy it in
  2786.     mov    word ptr modbuf.m_prn,'  '; assume not printing the screen
  2787.     mov    modbuf.m_prn+2,' '
  2788.     test    anspflg,prtscr+2    ; print the screen? (msz uses 1 & 2)
  2789.     jz    modl11            ; z = no
  2790.     mov    word ptr modbuf.m_prn,'RP' ; yes. display PRN at end of line
  2791.     mov    modbuf.m_prn+2,'N'
  2792. modl11:    call    getpos            ; get cursor position
  2793.     mov    cursor,dx        ; save cursor position
  2794.     mov    dx,offset modbuf    ; mode line image ptr for putmod
  2795.     call    putmod            ; display mode line
  2796.     cmp    flags.vtflg,0        ; emulating?
  2797.     je    modl12            ; e = no
  2798.     and    yflags,not modoff    ; update local flags (mode line on)
  2799.     call    ansdsl            ; get extras from emulator
  2800. modl12:    mov    dx,cursor
  2801.     pop    es
  2802.     jmp    setpos            ; reposition cursor
  2803. modlin    endp
  2804.  
  2805. trnprs:    push    ax            ; toggle ^ PrtSc screen to printer
  2806.     test    anspflg,prtscr        ; are we currently printing?
  2807.     jnz    trnpr2            ; nz = yes, its on and going off
  2808.     push    bx
  2809.     mov    bx,prnhand        ; file handle for system printer
  2810.     mov    ah,ioctl
  2811.     mov    al,7            ; get output status of printer
  2812.     int    dos
  2813.     pop    bx
  2814.     jc    trnpr1            ; c = printer not ready
  2815.     cmp    al,0ffh            ; Ready status?
  2816.     je    trnpr2            ; e = Ready    
  2817. trnpr1:    call    vtbell            ; Not Ready, complain
  2818.     jmp    trnpr3            ; and ignore request
  2819. trnpr2:    xor    anspflg,prtscr        ; flip the flag
  2820.     test    yflags,modoff        ; mode line off?
  2821.     jnz    trnpr3            ; nz = yes
  2822.     call    modlin            ; else rewrite mode line
  2823. trnpr3:    pop    ax
  2824.     clc                ; return carry clear (don't quit)
  2825.     ret
  2826.  
  2827.  
  2828. pntdead    proc    near            ; display printer is inoperative msg
  2829.     push    ax
  2830.     test    yflags,modoff        ; is mode line off?
  2831.     jnz    pntdea1            ; nz = off, skip msg
  2832.     push    bx
  2833.     mov    dx,offset pntmsg    ; say printer not ready
  2834.     call    putmod            ; write on mode line
  2835.     pop    bx
  2836. pntdea1:pop    ax
  2837.     stc                ; say printer not ready
  2838.     ret
  2839. pntdead    endp
  2840.  
  2841. ;;;;; General screen management routines for IBM PC
  2842.  
  2843. ; computes screen location to ax, given row and col in [dh,dl], resp.
  2844.  
  2845. scrloc    proc    near
  2846.     mov    al,dh            ; get row
  2847.     mul    crt_cols        ; multiply by number of columns
  2848.     add    al,dl            ; plus current column number
  2849.     adc    ah,0            ; ripple carry
  2850.     shl    ax,1            ; double for attributes
  2851.     ret
  2852. scrloc    endp
  2853.      
  2854. ; Routine to set cursor type.  Pass cursor type in al: 0 = No cursor,
  2855. ; 1 = Underline cursor, 2 = Block cursor.   All cursors blink due to hardware.
  2856. ; Routine frags any ac that video ints frag.
  2857. ; For EGA boards running in non-25 line mode the cursor emulation is turned
  2858. ; off during cursor shape changing and restored afterward. It's another
  2859. ; ega Feature. [jrd]
  2860. ; Sense crt_mode 18h as Tseng Labs UltraPAK mono board in 132 column mode.
  2861. csrtype proc    near
  2862.     push    cx            ; save the reg
  2863.     mov    cx,0F00H        ; assume no cursor
  2864.     or    al,al            ; no cursor?
  2865.     jz    csrty2            ; z = yes, no cursor
  2866.     cmp    crt_mode,7        ; B&W card?
  2867.     je    csrty3            ; e = yes, different sizes
  2868.     cmp    crt_mode,18h        ; Tseng UltraPAK mono board?
  2869.      je    csrty3            ; e = yes, use mono cursor
  2870.     mov    cx,0607H        ; No, use CGA underline cursor
  2871.     cmp    al,2            ; Block?
  2872.     jne    csrty2            ; ne = no, set it now
  2873. csrty1: xor    ch,ch            ; make cursor a block
  2874. csrty2:    cmp    ega_mode,0        ; ega board active?
  2875.     je    csrty4            ; e = no
  2876.     cmp    byte ptr low_rgt+1,23    ; standard screen length?
  2877.     je    csrty4            ; e = yes, use regular cursor setting
  2878.     push    es            ; EGA. turn off cursor emulation
  2879.     mov    ax,40h            ; 40:87h is ega Info byte
  2880.     mov    es,ax
  2881.     push    es:[87h]        ; save Info byte around call
  2882.     or    byte ptr es:[87h],1    ; set emulation off (low bit = 1)
  2883.     mov    ah,1            ; video function for set cursor type
  2884.     int    screen
  2885.     pop    es:[87h]        ; restore Info byte
  2886.     pop    es            ;  and our work register
  2887.     pop    cx
  2888.     ret
  2889. csrty4:    mov    ah,1            ; video function for set cursor type
  2890.     int    screen            ; regular cursor shape setting
  2891.     pop    cx
  2892.     ret     
  2893. csrty3: mov    cx,0B0CH        ; assume B&W underline cursor
  2894.     cmp    al,2            ; Block?
  2895.     jne    csrty2            ; ne = no, set it now
  2896.     jmp    short csrty1        ; make it a block
  2897. csrtype endp
  2898.  
  2899.  
  2900.  
  2901. ; Get CRT mode - returns mode in variable crt_mode,
  2902. ; updates crt_cols and low_rgt.
  2903. ; For EGA active it looks in Bios work memory 40:84H for number of rows
  2904. scrmod    proc    near
  2905.     push    ax
  2906.     push    dx
  2907.     mov    ah,15            ; get current video state
  2908.     int    screen
  2909.     and    al,not 80h        ; strip "preserve regen" bit 80h
  2910.     mov    crt_mode,al        ; store CRT mode value
  2911.     mov    crt_cols,ah        ; store # of cols
  2912.     mov    dl,ah            ; # of cols again
  2913.     mov    dh,crt_lins        ; and # of rows (constant from msster)
  2914.     cmp    ega_mode,0        ; ega active?
  2915.     je    scrmod4            ; e = no
  2916.     push    es            ; yes, permit different lengths
  2917.     mov    ax,40h            ; refer to 40:84h for # ega rows
  2918.     mov    es,ax
  2919.     mov    ah,es:[84h]        ; get number of rows - 1 (typ 24)
  2920.     cmp    ah,20            ; less than 20 rows?
  2921.     jb    scrmod3            ; b = yes, ignore this length
  2922.     cmp    ah,80            ; more than 80 rows?
  2923.     ja    scrmod3            ; a = yes, ignore this length
  2924.     mov    dh,ah            ; use this length
  2925.     mov    crt_lins,dh        ; update our working constant
  2926. scrmod3:pop    es
  2927. scrmod4:dec    dl            ; max text column, count from zero
  2928.     dec    dh            ; max text row, count from zero
  2929.     mov    low_rgt,dx        ; save away window address
  2930.     pop    dx
  2931.     pop    ax
  2932.     ret
  2933. scrmod    endp
  2934.  
  2935. ; Test for DESQview in operation, set tv_mode bit 10h to non-zero if so.
  2936. dvtest    proc    near
  2937.     push    di
  2938.     push    es
  2939.     mov    ax,tv_segs        ; seg of video memory
  2940.     mov    es,ax
  2941.     mov    di,tv_sego        ; set to video buffer beginning
  2942.     and    tv_mode,not 10h        ; assume no DV
  2943.     mov    cx,'DE'            ; DV signature
  2944.     mov    dx,'SQ'
  2945.     mov    ax,2B01h        ; DOS set date (with illegal value)
  2946.     int    dos
  2947.     cmp    al,0ffh            ; DOS should say invalid if no DV
  2948.     je    dvtest1            ; e = yes, invalid so no DV
  2949.     or    tv_mode,10h        ; say using DV
  2950. dvtest1:pop    es
  2951.     pop    di
  2952.     ret
  2953. dvtest    endp
  2954.  
  2955. ; Execute DESQview function call provided in BX.
  2956. dvcall    proc    near
  2957.     push    ax
  2958.     mov    ax,101ah        ; switch to DV stack
  2959.     int    15h
  2960.     mov    ax,bx            ; function to do
  2961.     int    15h
  2962.     mov    ax,1025h        ; switch from DV stack
  2963.     int    15h
  2964.     pop    ax
  2965.     ret
  2966. dvcall    endp
  2967.  
  2968. ; Call this to release the cpu during idle times
  2969. dvpause    proc    near
  2970.     test    tv_mode,10h        ; in DV?
  2971.     jz    dvpaus1            ; z = no
  2972.     push    bx
  2973.     mov    bx,1000h        ; say release control
  2974.     call    dvcall            ; to DV
  2975.     pop    bx
  2976. dvpaus1:ret
  2977. dvpause    endp
  2978.  
  2979. ; Get screen segment - returns screen segment in ax, and full address in es:di
  2980.  
  2981. scrseg    proc    near
  2982.     xor    di,di            ; start at beginning of screen (0,0)
  2983.     mov    ax,0B800H        ; video memory is here on color
  2984.     cmp    crt_mode,7        ; normal color modes?
  2985.     jb    scrse1            ; b = yes
  2986.     mov    ax,0B000H        ; assume B&W card
  2987.     cmp    crt_mode,12        ; 
  2988.     jb    scrse1
  2989.     cmp    crt_mode,18h        ; Tseng UltraPAK mono in 132 col?
  2990.     je    scrse1            ; e = yes, use seg B000H
  2991.     cmp    crt_mode,56h        ; Paradise EGA Mono in 132x43 mode?
  2992.     je     scrse1            ; e = yes, use seg B000H
  2993.     cmp    crt_mode,57h        ; Paradise EGA Mono in 132x25 mode?
  2994.     je    scrse1            ; e = yes, use seg B000H
  2995.     mov    ax,0B800H        ; video memory is here on color
  2996.     cmp    crt_mode,18        ; end of ordinary 640x480 graphics
  2997.     ja    scrse1            ; a = no, assume CGA segment
  2998.     mov    ax,0A000H        ; graphics
  2999. scrse1:    mov    es,ax        ; tell Topview our hardware address needs
  3000.     mov    tv_segs,es        ; save our hardware screen address
  3001.     mov    tv_sego,di        ; segment and offset form
  3002.     or    tv_mode,1        ; assume we're running under Topview
  3003.     mov    ah,tvhere        ; query Topview for its presence
  3004.     int    screen
  3005.     mov    ax,es            ; get its new segment for screen work
  3006.     cmp    ax,tv_segs        ; same as hardware?
  3007.     jne    scrse2            ; ne = no, we are being mapped
  3008.     cmp    di,tv_sego        ; check this too
  3009.     jne    scrse2        ; ne = no too. Use TV's work buf as screen
  3010.     and    tv_mode,not 1        ; else no Topview or no mapping
  3011. scrse2:    mov    tv_segs,es        ; save segment
  3012.     mov    tv_sego,di        ; and offset
  3013.     ret
  3014. scrseg    endp
  3015.  
  3016. ; Synchronize a Topview provided virtual screen buffer with the image
  3017. ; seen by the user. Requires cx = number of words written to screen
  3018. ; (char & attribute bytes) and es:di = ENDING address of screen write.
  3019. ; Changes ax and di.
  3020. scrsync    proc    near
  3021.     cmp    tv_mode,0        ; Topview mode active?
  3022.     je    scrsyn1            ; e = no, skip DOS call below
  3023.     sub    di,cx            ; backup to start byte (cx = words)
  3024.     sub    di,cx            ;  after storing words to screen
  3025.     mov    ah,tvsynch        ; tell Topview we have changed screen
  3026.     int    screen            ;  so user sees updated screen
  3027. scrsyn1:ret
  3028. scrsync    endp
  3029.  
  3030. ; The following two routines are used to turn off the display while we
  3031. ; are reading or writing the screen in one of the color card modes.
  3032. ; Turn screen off for (known) color card modes only. All regs preserved.
  3033. ; Includes code for old procedure scrwait. 16 June 1987 [jrd]
  3034. scroff    proc    near
  3035.     cmp    ega_mode,0        ; Extended Graphics Adapter in use?
  3036.     jne    scrofx            ; ne = yes, no waiting
  3037.     cmp    tv_mode,0        ; Topview mode?
  3038.     jne    scrofx            ; ne = yes, no waiting
  3039.     cmp    crt_mode,7        ; B&W card?
  3040.     jnb    scrofx            ; nb = yes - just return
  3041.     cmp    refresh,0        ; slow refresh?
  3042.     jne    scrofx            ; ne = no wait
  3043.     push    ax            ; save ax and dx
  3044.     push    dx
  3045.     mov    dx,crt_status        ; CGA: Wait for vertical retrace
  3046. scrof1:    in    al,dx
  3047.     test    al,disp_enb        ; display enabled?
  3048.     jnz    scrof1            ; yes, keep waiting
  3049. scrof2:    in    al,dx
  3050.     test    al,disp_enb        ; now wait for it to go off
  3051.     jz    scrof2            ; so can have whole cycle
  3052.     mov    dx,crtmset        ; output to CRT mode set port
  3053.     mov    al,25H            ; this shuts down the display
  3054.     out    dx,al
  3055.     pop    dx            ; restore regs
  3056.     pop    ax
  3057. scrofx: ret
  3058. scroff    endp
  3059.  
  3060.  
  3061. ; Turn screen on for (known) color card modes only
  3062. ; All registers are preserved.
  3063.  
  3064. scron    proc    near
  3065.     cmp    ega_mode,0        ; Extended Graphics Adapter in use?
  3066.     jne    scronx            ; ne = yes, no waiting
  3067.     cmp    tv_mode,0        ; Topview mode?
  3068.     jne    scronx            ; ne = yes, no waiting
  3069.     cmp    crt_mode,7        ; B&W card?
  3070.     jnb    scronx            ; nb = yes - just return
  3071.     cmp    refresh,0        ; slow refresh?
  3072.     jne    scronx            ; ne = no wait
  3073.     push    ax            ; save ax, dx, and si
  3074.     push    dx
  3075.     push    si
  3076.     mov    al,crt_mode        ; convert crt_mode to a word
  3077.     xor    ah,ah
  3078.     mov    si,ax            ; get it in a usable register
  3079.     mov    al,msets[si]        ; fetch the modeset byte
  3080.     mov    dx,crtmset        ; this port
  3081.     out    dx,al            ; flash it back on
  3082.     pop    si
  3083.     pop    dx
  3084.     pop    ax
  3085. scronx: ret
  3086. scron    endp
  3087.  
  3088.  
  3089. ; Screen clearing routine. [IU]
  3090. ;
  3091. ; Call:        ax/    coordinates of first screen location to be cleared.
  3092. ;        bx/    coordinates of last location to be cleared.
  3093. ; Coord: ah = row [0-24], al = column [0-79]. Preserves all registers. [jrd]
  3094.  
  3095. atsclr:    push    ax            ; save regs 
  3096.     push    cx
  3097.     push    dx
  3098.     mov    dx,bx            ; compute last screen offset in ax
  3099.     push    ax
  3100.     call    scrmod            ; update column length
  3101.     pop    ax            ; scrmod zaps ax
  3102.     push    ax
  3103.     call    scrloc            ; get screen start address in ax
  3104.     mov    cx,ax            ; save it in cx for a minute
  3105.     pop    dx            ; compute first screen offset in ax
  3106.     call    scrloc
  3107.     sub    cx,ax            ; compute number of locs to clear
  3108.     add    cx,2
  3109.     sar    cx,1            ; make byte count a word count
  3110.     jle    atscl2            ; If nothing to clear, then vamos
  3111.     push    di            ; save regs
  3112.     push    es            ; save es
  3113.     push    ax            ; save displacement
  3114.     call    scrseg            ; get address of screen into es:di
  3115.     pop    di            ; displacement memory address into di
  3116.     mov    ah,scbattr        ; use current screen background attr
  3117.     mov    al,' '            ; use space for fill
  3118.     call    scroff            ; turn screen off if color card
  3119. atscl1:    push    cx            ; save word count for Topview
  3120.     cld
  3121.     rep    stosw            ; Blit... (excuse PDP-10ese please)
  3122.     pop    cx            ; recover word count
  3123.     call    scrsync            ; synch Topview
  3124.     call    scron            ; Turn screen back on if color card
  3125.     pop    es            ; Restore segment register
  3126.     pop    di            ; And destination index
  3127. atscl2:    pop    dx            ; restore regs
  3128.     pop    cx
  3129.     pop    ax
  3130.     ret
  3131.  
  3132. ; Scrolling routines.  vtscru scrolls up, vtscrd scrolls down 'scroll'
  3133. ; rows. Top lines are saved in the circular buffer before scrolling up.
  3134. ; When running under an Environment control number of line positions moved
  3135. ; to be less than scrolling region.
  3136. ; All registers are preserved.
  3137. ;
  3138. ; Screen-roll down. Move text down one line, for terminal emulator only.
  3139. ;
  3140. vtscrd: push    ax
  3141.     push    bx
  3142.     push    cx
  3143.     push    dx
  3144.     mov    ax,0700h        ; scroll down whole region
  3145.     mov    ch,mar_top        ; top margin line
  3146.     xor    cl,cl            ; left most column
  3147.     mov    dh,mar_bot        ; bottom margin line
  3148.     mov    dl,byte ptr low_rgt    ; right most column
  3149.     mov    bh,scbattr        ; attributes
  3150.     mov    bl,dh
  3151.     sub    bl,ch            ; region size - 1 line
  3152.     jz    vscrd1             ; z = region is 1 line, do one scroll
  3153.     mov    al,scroll        ; number of lines to scroll, from msz
  3154. vscrd1:    cmp    al,bl            ; want to scroll more that than?
  3155.     jbe    vscrd2            ; be = no
  3156.     push    ax
  3157.     mov    al,bl            ; limit to region-1 for Windows
  3158.     int    screen            ;  and do in parts
  3159.     pop    ax
  3160.     sub    al,bl            ; get remainder
  3161.     jmp    short vscrd1        ; do next part
  3162. vscrd2:    int    screen            ; scroll it down
  3163.     pop    dx
  3164.     pop    cx
  3165.     pop    bx
  3166.     pop    ax
  3167.     ret
  3168.      
  3169. ; Screen scroll up one line (text moves up) for terminal emulator use.
  3170. ; When running under an Environment control number of line positions moved
  3171. ; to be less than scrolling region.
  3172.      
  3173. vtscru: push    ax
  3174.     push    bx
  3175.     push    cx
  3176.     push    dx
  3177.     xor    ch,ch
  3178.     mov    cl,scroll        ; number of lines to scroll
  3179.     or    cl,cl
  3180.     jnz    vscru5
  3181.     jmp    vscru3            ; z = nothing to do
  3182. vscru5:    cmp    mar_top,0        ; scrolling the top screen line?
  3183.     ja    vscru2            ; a = no. don't save anything
  3184.     push    si
  3185.     push    di
  3186.     push    cx            ; (BDT) save this around the call
  3187.     call    putcirc            ; put screen lines in circular buffer
  3188.     pop    cx            ; (BDT) restore the register
  3189.     add    linec,cx        ; (BDT) increment the current line
  3190.     mov    cx,linec        ; new current line number
  3191.     sub    cx,lcnt            ; minus # in buf = qty new lines added
  3192.     jc    vscru4            ; c = not extending buffer
  3193.     add    lcnt,cx            ; (BDT) increment the line counter
  3194. vscru4:
  3195.     mov    cx,lcnt            ; (BDT) check: are we
  3196.     cmp    cx,lmax            ; (BDT) beyond the end?
  3197.     jbe    vscru1b            ; (BDT) be = no
  3198.     sub    cx,lmax            ; (BDT) compute overflow count
  3199.     add    linef,cx        ; (BDT) adjust the "first" line
  3200.     mov    cx,linef        ; (BDT) check: time to wrap?
  3201.     cmp    cx,linee        ; (BDT) ...
  3202.     jb    vscru1            ; (BDT) b = no
  3203.     sub    cx,linee        ; (BDT) yup
  3204.     mov    linef,cx        ; (BDT) adjust it
  3205. vscru1:    mov    cx,lmax            ; (BDT) get the maximum line count
  3206.     mov    lcnt,cx            ; (BDT) reset the line counter
  3207.     mov    linec,cx        ; (BDT) reset the current line
  3208. vscru1b:
  3209.     pop    di
  3210.     pop    si            ; now scroll the visible screen
  3211. vscru2: mov    ax,0600h        ; scroll up whole region
  3212.     mov    dh,mar_bot        ; bottom row
  3213.     mov    dl,byte ptr low_rgt    ; right most column
  3214.     mov    ch,mar_top        ; top row of scrolling region
  3215.     xor    cl,cl            ; left most column
  3216.     mov    bh,scbattr        ; attributes
  3217.     mov    bl,dh
  3218.     sub    bl,ch            ; region size - 1 line
  3219.     jz    vscru2b            ; z = region is 1 line, do one scroll
  3220.     mov    al,scroll        ; number of lines to scroll, from msz
  3221. vscru2a:cmp    al,bl            ; want to scroll more that than?
  3222.     jbe    vscru2b            ; be = no
  3223.     push    ax
  3224.     mov    al,bl            ; limit to region - 1 for Windows
  3225.     int    screen            ;  and do in parts
  3226.     pop    ax
  3227.     sub    al,bl
  3228.     jmp    short vscru2a        ; do next part
  3229. vscru2b:int    screen            ; scroll up that region
  3230. vscru3:    pop    dx            ; restore the rest of the regs
  3231.     pop    cx
  3232.     pop    bx
  3233.     pop    ax
  3234.     ret
  3235.  
  3236. ; (BDT) new screen-scrolling routines.  Single, circular buffer
  3237.      
  3238. homwnd    proc    near            ; "home" to start of the buffer
  3239.     push    cx            ; save registers
  3240.     mov    cx,lxtra        ; save this many lines
  3241.     call    putcirc            ; save them
  3242.     mov    linec,0            ; reset the current pointer
  3243.     call    getcirc            ; now get the new screen
  3244.     pop    cx            ; restore registers
  3245.     clc
  3246.     ret
  3247. homwnd    endp
  3248.      
  3249. endwnd    proc    near            ; "end" to end of the buffer
  3250.     push    cx            ; save registers
  3251.     mov    cx,lxtra        ; save this many lines
  3252.     call    putcirc            ; save them
  3253.     mov    cx,lcnt            ; reset the current pointer
  3254.     mov    linec,cx        ; save the results
  3255.     call    getcirc            ; now get the new screen
  3256.     pop    cx            ; restore registers
  3257.     clc
  3258.     ret
  3259. endwnd    endp
  3260.      
  3261. dnwpg    proc    near            ; scroll down 1 page
  3262.     push    cx            ; save registers
  3263.     mov    cx,lxtra        ; save this many lines
  3264.     call    putcirc            ; save them
  3265.     mov    cx,linec        ; reset the current pointer
  3266.     add    cx,lxtra        ;  to the next page
  3267.     cmp    cx,lcnt            ; did we go past the end?
  3268.     jbe    dnwpg1            ; be = no, we're OK
  3269.     mov    cx,lcnt            ; yup, back up
  3270. dnwpg1:
  3271.     mov    linec,cx        ; save the results
  3272.     call    getcirc            ; now get the new screen
  3273.     pop    cx            ; restore registers
  3274.     clc
  3275.     ret
  3276. dnwpg    endp
  3277.      
  3278. dnone    proc    near            ; scroll down 1 line
  3279.     push    cx            ; save registers
  3280.     mov    cx,lxtra        ; save this many lines
  3281.     call    putcirc            ; save them
  3282.     mov    cx,linec        ; reset the current pointer
  3283.     inc    cx            ;  to the next line
  3284.     cmp    cx,lcnt            ; oops, did we go past the end?
  3285.     jbe    dnone1            ; be = no, we're OK
  3286.     mov    cx,lcnt            ; yup, back up
  3287. dnone1:
  3288.     mov    linec,cx        ; save the results
  3289.     call    getcirc            ; now get the new screen
  3290.     pop    cx            ; restore registers
  3291.     clc
  3292.     ret
  3293. dnone    endp
  3294.      
  3295. upwpg    proc    near            ; scroll up 1 page
  3296.     push    cx            ; save registers
  3297.     mov    cx,lxtra        ; save this many lines
  3298.     call    putcirc            ; save them
  3299.     mov    cx,linec        ; reset the current pointer
  3300.     sub    cx,lxtra        ;  to the previous page
  3301.     jge    upwpg1            ; ge = not past end, we're OK
  3302.     xor    cx,cx            ; yup, back up
  3303. upwpg1:
  3304.     mov    linec,cx        ; save the results
  3305.     call    getcirc            ; now get the new screen
  3306.     pop    cx            ; restore registers
  3307.     clc
  3308.     ret
  3309. upwpg    endp
  3310.      
  3311. upone    proc    near            ; scroll up 1 line
  3312.     push    cx            ; save registers
  3313.     mov    cx,lxtra        ; save this many lines
  3314.     call    putcirc            ; save them
  3315.     mov    cx,linec        ; reset the current pointer
  3316.     sub    cx,1            ;  to the previous line
  3317.     jge    upone1            ; ge = not past end, we're OK
  3318.     xor    cx,cx            ; yup, back up
  3319. upone1:
  3320.     mov    linec,cx        ; save the results
  3321.     call    getcirc            ; now get the new screen
  3322.     pop    cx            ; restore registers
  3323.     clc
  3324.     ret
  3325. upone    endp
  3326.      
  3327. ; Put cx lines into the circular buffer.
  3328. ; Source is tv_segs:si which is the current screen address.
  3329. putcirc    proc    near            ; put lines in the circular buffer
  3330.     jcxz    putcir9            ; z = no lines to save
  3331.     cmp    lmax,0            ; any buffer space?
  3332.     je    putcir9            ; e = no, nothing saved here
  3333.     push    es            ; save ES for a tad
  3334.     call    scroff            ; turn off the screen
  3335.     mov    si,tv_sego        ; initial screen offset
  3336.     mov    ax,linef        ; get the first line pointer
  3337.     add    ax,linec        ; add the current line counter
  3338.     dec    ax            ; get a running start
  3339. putcir1:inc    ax            ; increment the current line pointer
  3340.     cmp    ax,linee        ; fallen off the end of the buffer?
  3341.     jb    putcir2            ; b = no, proceed
  3342.     sub    ax,linee        ; back up to the buffer start
  3343. putcir2:push    ax            ; save the current line pointer
  3344.     mul    ppl            ; compute the paragraph offset
  3345.     add    ax,iniseg        ; add the initial segment
  3346.     mov    es,ax            ; now we have the segment pointer
  3347.     xor    di,di            ; initial buffer offset is 0
  3348.     push    cx            ; save the number of lines
  3349.     xor    ch,ch            ; get the number of characters to move
  3350.     mov    cl,crt_cols
  3351.     push    ds            ; get the offset of the screen
  3352.     mov    ds,tv_segs        ; get the segment of the screen
  3353.     rep    movsw            ; move them
  3354.     pop    ds            ; restore DS
  3355.     pop    cx            ; restore the line count
  3356.     pop    ax            ; restore the buffer counter
  3357.     loop    putcir1            ; go back for more
  3358.     call    scron            ; turn the screen back on
  3359.     pop    es            ; restore ES
  3360. putcir9:ret
  3361. putcirc    endp
  3362.  
  3363. ; Get CX lines from the circular buffer, non destructivly.
  3364. ; Destination preset in es:di which is the current screen address.
  3365. getcirc    proc    near            ; get lines from the circular buffer
  3366.     mov    cx,lxtra        ; restore this many lines
  3367.     jcxz    getcir3            ; z = nothing to do
  3368.     call    scroff            ; turn off the screen
  3369.     push    es            ; save ES for a tad
  3370.     mov    es,tv_segs        ; get the segment of the screen
  3371.     mov    di,tv_sego        ; initial screen offset
  3372.     mov    ax,linef        ; get the first line pointer
  3373.     add    ax,linec        ; add the current line counter
  3374.     dec    ax            ; get a running start
  3375. getcir1:inc    ax            ; increment the current line pointer
  3376.     cmp    ax,linee        ; fallen off the end of the buffer?
  3377.     jb    getcir2            ; b = no, proceed
  3378.     sub    ax,linee        ; back up to the buffer start
  3379. getcir2:push    ax            ; save the current line pointer
  3380.     mul    ppl            ; compute the paragraph offset
  3381.     add    ax,iniseg        ; add the initial segment
  3382.     xor    si,si            ; initial offset is 0
  3383.     push    cx            ; save the number of lines
  3384.     xor    ch,ch            ; get the number of characters to move
  3385.     mov    cl,crt_cols        ;  ...
  3386.     push    ds            ; save DS for a tad
  3387.     mov    ds,ax            ; now we have the segment pointer
  3388.     rep    movsw            ; move them
  3389.     pop    ds            ; restore DS
  3390.     pop    cx            ; restore the line count
  3391.     push    di            ; save around update call
  3392.     call    scrsync            ; synch Topview
  3393.     pop    di
  3394.     pop    ax            ; restore the buffer counter
  3395.     loop    getcir1            ; go back for more
  3396.     call    scron            ; turn the screen back on
  3397.     pop    es            ; restore ES
  3398. getcir3:ret
  3399. getcirc    endp
  3400.  
  3401. ;
  3402. ; CHKDSP - procedure to check for hardware support of 132 cols
  3403. ;  Supported hardware:
  3404. ;  ATI EGA and VGA Wonder
  3405. ;  AT&T
  3406. ;  Everex Viewpoint EV-659, FVGA-673, EV-678, Micro Enhancer Deluxe
  3407. ;  IBM XGA
  3408. ;  Paradise AutoSwitch EGA Mono, VGA Professional, VGA Plus, VGA Plus 16
  3409. ;  STB VGA/EM (Tseng TVGA)
  3410. ;  STB VGA/EM Plus (Tseng 4000), VGA/EM-16, VGA/EM-16 Plus
  3411. ;  Tseng Labs EVA board w/132-col kit installed
  3412. ;  Tseng Labs UltraPAK mono/Herc board w/132 column modes.
  3413. ;  Video 7 Vega Deluxe w/ 132X25.COM driver installed and VGA board.
  3414. ; The routine checks for the presence of a 132-column-capable adapter. If
  3415. ; one is found its handler executes the desired mode setting and returns
  3416. ; carry clear; it returns carry set otherwise.
  3417. ; Adding new boards - place an identification string in the data segment,
  3418. ; construct a mode setting routine and insert it in the call list below
  3419. ; (setting 132 column mode is byte AL non-zero). Byte AH is non-zero to
  3420. ; avoid saving old screen and running scrini; it is used to set the screen
  3421. ; width when starting/exiting Connect mode
  3422. ;
  3423. chgdsp    proc    near
  3424.     push    es            ; save all we use
  3425.     push    ax
  3426.     push    bx
  3427.     push    cx
  3428.     push    dx
  3429.     push    si
  3430.     push    di
  3431.     mov    temp,ax            ; save set/reset flag from msz
  3432.     cmp    crt_cols,80        ; are we narrow?
  3433.     jbe    chgds3            ; be = narrow width now
  3434.     or    al,al            ; resetting to narrow width?
  3435.     jz    chgds4            ; z = yes, do it
  3436.     jmp    chgdsx1            ; else we are there now
  3437. chgds3:    or    al,al            ; resetting to narrow width?
  3438.     jnz    chgds4            ; nz = no, setting to wide
  3439.     jmp    chgdsx1            ; narrow width, we are there now
  3440. chgds4:    or    ah,ah            ; are we connected now?
  3441.     jnz    chgds0            ; nz = no, skip flow control etc
  3442.     mov    ah,flowoff        ; get xoff
  3443.     or    ah,ah            ; flow control?
  3444.     jz    chgds4a            ; z = none
  3445.     call    outchr            ; send it
  3446. chgds4a:cmp    byte ptr temp+1,0    ; exiting Connect mode?
  3447.     jne    chgds0            ; ne = yes
  3448.     call    savescr            ; save current screen
  3449.     mov    ax,500            ; wait 500 millisec before video tests
  3450.     call    pcwait            ; so don't mix screen and port intrpts
  3451.  
  3452. chgds0:    call    ckteva            ; try Tseng Labs EVA
  3453.     jnc    chgds1            ; nc = found
  3454.     call    ckstbv            ; try STB VEGA/EM
  3455.     jnc    chgds1            ; nc = found
  3456.     call    ckv7vd            ; try Video 7 EGA Deluxe and VGA
  3457.     jnc    chgds1            ; nc = found
  3458.     call    ckatiw            ; try ATI EGA Wonder
  3459.     jnc    chgds1            ; nc = found
  3460.     call    ckevrx                  ; try Everex Micro Enhancer Deluxe
  3461.     jnc     chgds1                  ; nc = found
  3462.     call    ckevga            ; try Everex EVGA-673
  3463.     jnc     chgds1                  ; nc = found
  3464.     call    ckatt            ; ATT boards
  3465.     jnc    chgds1            ; nc = found
  3466.     call    chkpa            ; Paradise EGA/VGA boards
  3467.     jnc    chgds1            ; nc = found
  3468.     call    ckxga            ; IBM XGA
  3469.     jnc    chgds1            ; nc = found
  3470.     mov    si,offset cols80    ; name of 80 column file
  3471.     cmp    byte ptr temp,0        ; setting 80 cols?
  3472.     je    chgdsx2            ; e = yes
  3473.     mov    si,offset cols132    ; use 132 column file
  3474. chgdsx2:mov    di,offset dumpbuf    ; a temp buffer for path= usage
  3475.     call    strcpy
  3476.     mov    ax,di            ; spath wants ptr in ax
  3477.     call    spath
  3478.     jc    chgdsx            ; c = file not found
  3479.     mov    si,ax            ; crun wants ptr in si
  3480.     call    crun            ; run the batch file, si = filespec
  3481.     call    serini            ; reengage serial port, mode changes
  3482.     mov    ax,0c06h        ; clear kbd buffer and do function
  3483.     mov    dl,0ffh            ; console input
  3484.     int    dos            ; discard character(s)
  3485.                     ; Perform mode change
  3486. chgds1:    cmp    byte ptr temp+1,0    ; do without scrini stuff?
  3487.     jne    chgdsx1            ; ne = yes
  3488.     cmp    flags.modflg,1        ; is mode line enabled?
  3489.     jbe    chgds2            ; be = yes, and off or locally owned
  3490.     mov    flags.modflg,1        ; remove foreign ownership
  3491. chgds2:    call    scrini            ; reset parameters
  3492. chgdsx:    mov    ah,flowon        ; get flowon byte
  3493.     or    ah,ah            ; using flow control?
  3494.     jz    chgdsx1            ; z = no
  3495.     call    outchr            ; send it
  3496. chgdsx1:pop    di            ; restore what we saved
  3497.     pop    si
  3498.     pop    dx
  3499.     pop    cx
  3500.     pop    bx
  3501.     pop    ax
  3502.     pop    es
  3503.     ret                ; return to caller
  3504.      
  3505. ; Individual tests for various 132-column boards
  3506.                     ; Tseng LABS EVA and UltraPAK
  3507. ckteva: mov    ax,0c000h        ; seg addr for EVA
  3508.     mov    es,ax            ; set into es register
  3509.     mov    di,76h            ; offset of board's string
  3510.     lea    si,tsngid        ; validation string
  3511.     mov    cx,tsnglen        ; length of validiation string
  3512.     cld
  3513.     repe    cmpsb            ; compare strings
  3514.     je    ckteva2            ; e = strings match
  3515.     mov    ax,4d00h        ; check for UltraPAK mono driver
  3516.     int    screen
  3517.     cmp    ax,5aa5h        ; driver signature?
  3518.      jne    ckteva3            ; ne = no
  3519.     mov    ax,7            ; default to mono (7) for this board
  3520.     cmp    byte ptr temp,0        ; setting 132 columns?
  3521.     je    ckteva1            ; e = resetting to normal
  3522.     mov    ax,18h            ; set to 132 cols (Set Mode 18H)
  3523. ckteva1:int    screen
  3524.     clc                ; carry clear means success
  3525.     ret
  3526.                     ; an EVA board - check for 132 col kit
  3527. ckteva2:cmp    byte ptr es:099h,0    ; check 132 col kit installed
  3528.     jne    catfnd            ; ne = installed, do the mode change
  3529. ckteva3:stc                ; indicate adapter not present
  3530.     ret                ; and exit
  3531.                     ;
  3532. ckstbv:    mov    ax,0c000h        ; STB's VGA/EM, VGA/EM-16, EM-16 Plus
  3533.     mov    es,ax            ;
  3534.     mov    di,70h            ; where to look for signature
  3535.     lea    si,stbvid        ; the signature
  3536.     mov    cx,stbvlen        ;
  3537.     cld                ;
  3538.     repe    cmpsb            ; test
  3539.     je    catfnd            ; e = found
  3540.     mov    di,70h            ; where to look for signature
  3541.     lea    si,stavid        ; the signature
  3542.     mov    cx,stavlen
  3543.     cld
  3544.     repe    cmpsb            ; test
  3545.     je    catfnd            ; e = found
  3546.     stc                ; else say not there
  3547.     ret                ;
  3548.                     ; ATI EGA Wonder
  3549. ckatiw:    mov    ax,0c000h        ; seg addr for EGA Wonder
  3550.     mov    es,ax            ; set into es register
  3551.     mov    di,012fh        ; offset of message in ROM
  3552.     lea    si,atiwid        ; offset of message here
  3553.     mov    cx,atilen        ; length of validation string
  3554.     cld
  3555.     repe    cmpsb            ; compare strings
  3556.     je    catfnd            ; e = they match
  3557.     lea    si,atiwid2        ; alternative signature
  3558.     mov    di,30h            ; start at this offset
  3559.     mov    cx,atilen2        ; alternative signature length
  3560.     mov    ax,es:[di]        ; get first two bytes
  3561.     cmp    al,atiwid2        ; string starts here?
  3562.      je    ckatiw1            ; e = yes
  3563.     inc    di            ; try next location, just in case
  3564.     cmp    ah,atiwid2        ; or here?
  3565.     je    ckatiw1            ; e = yes
  3566.     stc                ; strings differ
  3567.     ret
  3568. ckatiw1:repe    cmpsb            ; check the whole string
  3569.     je    catfnd            ; e = matches the whole thing
  3570.     stc                ; fail on mismatch
  3571.     ret
  3572. catfnd:    mov    ax,0003h        ; prepare to reset video mode
  3573.     cmp    byte ptr temp,0        ; are we setting or resetting?
  3574.     je    catfnd1            ; e is reset, exit
  3575.     mov    ax,0023h        ; set to 132 cols (Set Mode 23H)
  3576. catfnd1:int    screen
  3577.     clc                ; carry clear means success
  3578.     ret
  3579.  
  3580. chkpa:    mov    ax,0c000h        ; load Paradise ROM BIOS address
  3581.     mov    es,ax
  3582.     mov    ax,0057h        ; assume 132x25 mono display needed
  3583.     mov    di,0009h        ; load EGA board identifier index
  3584.     lea    si,pmega1        ; Paradise Autoswitch Mono ident
  3585.     mov    cx,pmegal1
  3586.     cld
  3587.     repe    cmpsb            ; do identification strings match?
  3588.     je    chgpa2            ; e = yes, check num of display lines
  3589.     mov    di,007dh        ; no, load VGA board identifier index
  3590.     lea    si,p30id        ; Paradise VGA, other flavors
  3591.     mov    cx,p30ln
  3592.     repe    cmpsb            ; do identification strings match?
  3593.     je    chgpa1            ; e = yes, check for color mode
  3594.     stc                ; fail
  3595.     ret
  3596. chgpa1:    cmp    crt_norm,3        ; is the "normal" screen in color?
  3597.     ja    chgpa2            ; a = no, orig assumption is correct
  3598.     mov    ax,0055h        ; assume 132x25 color required
  3599. chgpa2:    cmp    crt_lins,25        ; is the "normal" screen 25 lines?
  3600.     jna    chgpa3            ; na = yes, check num of cols needed
  3601.     dec    ax            ; change assumption to 132x43
  3602. chgpa3:    cmp    byte ptr temp,0        ; switching to a 132 column mode?
  3603.     jne    chgpa4            ; ne = yes
  3604.     mov    al,crt_norm        ; load "normal" display mode
  3605. chgpa4:    int    screen            ; issue BIOS call to change display
  3606.     clc                ; success
  3607.     ret
  3608.                     ; Video 7 Vega Deluxe
  3609. ckv7vd:    mov    ax,0c000h        ; seg addr for Vega rom bios
  3610.     mov    es,ax            ; set into es register
  3611.     mov    di,002ah        ; offset of message in ROM
  3612.     lea    si,vid7id        ; offset of message here
  3613.     mov    cx,vid7len
  3614.     cld
  3615.     repe    cmpsb            ; compare strings
  3616.     je    cnv7fn1            ; e = same
  3617.     mov    di,002ah        ; offset of ident string
  3618.     mov    si,offset vid7id2    ; Video 7 VGA board
  3619.     mov    cx,vid7len2
  3620.     repe    cmpsb
  3621.     je    cnv7fn2            ; e = found
  3622. cnv7fx:    stc                ; strings are different
  3623.     ret
  3624.                     ;
  3625. cnv7fn1:test    byte ptr es:[03ffeh],1    ; is this a 'Deluxe' Vega?
  3626.     jz    cnv7fx            ; z = nope, can't do it
  3627.     mov    ah,35h            ; DOS Get Vector
  3628.     mov    al,10h            ; Bios video interrupt
  3629.     int    dos            ; get it into es:bx
  3630.     mov    di,bx            ; es:bx is returned int 10h entry pnt
  3631.     sub    di,5ah            ; back offset to msg in 132X25.COM
  3632.     lea    si,vid7id        ; offset of validation message
  3633.     mov    cx,vid7len        ; length of validation string
  3634.     cld
  3635.     repe    cmpsb            ; Look for repeat of msg by 132X25.COM
  3636.     jne    cnv7fn2            ; if different
  3637.     mov    al,crt_mode        ; prepare to reset video mode
  3638.     xor    ah,ah
  3639.     cmp    byte ptr temp,0        ; are we setting or resetting?
  3640.     je    cnv7fn2a        ; e is reset
  3641.     mov    ax,0000h        ; set to 132 cols (old 40x25)
  3642. cnv7fn1a:int    screen
  3643.     clc
  3644.     ret
  3645.  
  3646. cnv7fn2:mov    ax,6f00h        ; check for VegaBios driver
  3647.     int    screen
  3648.     cmp    bx,'V7'            ; Video 7 Bios presence response
  3649.     jne    cnv7fx            ; ne = not there
  3650.     mov    ax,6f01h        ; al gets monitor type (mono,color,ega)
  3651.     int    screen
  3652.     mov    bx,51h            ; presume mono 132x25, page 0
  3653.     cmp    crt_lins,42        ; 43 lines active?
  3654.     jb    cnv7fn2a        ; b = no
  3655.     inc    bx            ; use bx = 52h for 132x43
  3656. cnv7fn2a:
  3657.     cmp    al,10h            ; analogue fixed freq (IBM 85xx)?
  3658.     je    cnv7fx            ; e = yes, no 132 columns
  3659.     cmp    al,2            ; 1 = mono, 2 = color, above = ega
  3660.     jb    cnv7fn3            ; b = mono or unknown
  3661.     mov    bx,4fh            ; presume med res color 132x25
  3662.     je    cnv7fn3            ; e = med res color, al = 2
  3663.     mov    bx,41h            ; ega high res 132x25, enhanced mons
  3664.     cmp    crt_lins,42        ; 43 lines active?
  3665.     jb    cnv7fn3            ; b = no
  3666.     inc    bx            ; use bx = 42h for 132x43
  3667. cnv7fn3:mov    ax,6f05h        ; set special mode found in bl
  3668.     cmp    byte ptr temp,0        ; resetting to 80 column mode?
  3669.     jne    cnv7fn4            ; ne = no, setting 132x25
  3670.     mov    al,crt_norm        ; get normal mode
  3671.     xor    ah,ah            ; set mode
  3672.     cmp    crt_lins,42        ; 43 lines active?
  3673.     jb    cnv7fn4            ; b = no
  3674.     mov    bl,40h            ; use Video 7 mode 40h 80x43 for color
  3675.     mov    ax,6f05h        ; and do special mode set
  3676. cnv7fn4:int    screen            ; special mode is in bl
  3677.     mov    ax,0f00h        ; a nop screen bios command
  3678.     int    screen
  3679.     clc
  3680.     ret
  3681.  
  3682. ckevrx: mov     ax,0c000h               ; seg addr for Everex EV-659
  3683.         mov     es,ax                   ; set into es register
  3684.         mov     di,0047h                ; offset of message in ROM
  3685.         lea     si,evrxid               ; offset of message here
  3686.         mov     cx,evrxlen              ; length of validation string
  3687.         cld
  3688.         repe    cmpsb                   ; compare strings
  3689.         jne     ckfnr2                  ; ne = strings differ
  3690.         mov     ah,crt_lins             ; we recognize either 44 or 25 rows
  3691.         cmp     ah,43                   ; equal to 44-1 rows?
  3692.         jne     ckfnr1                  ; ne = no
  3693.         mov     ax,0070h                ; Everex extended mode ident
  3694.         mov     bl,09h                  ; prepare to reset video mode to 80x44
  3695.         cmp     byte ptr temp,0         ; are we setting or resetting?
  3696.         je      ckfnr4                  ; e is reset, exit
  3697.         mov     bl,0bh                  ; 132x44
  3698.     int    screen
  3699.     clc
  3700.     ret
  3701. ckfnr1: cmp     ah,24                   ; equal to 25-1 rows?
  3702.     je    ckfnr3            ; e = yes
  3703. ckfnr2:    stc                ; return failure
  3704.     ret
  3705. ckfnr3:    mov     ax,0003h                ; prepare to reset video mode
  3706.         cmp     byte ptr temp,0         ; are we setting or resetting?
  3707.         je      ckfnr4                  ; e is reset, exit
  3708.         mov     ax,0070h                ; Everex extended mode ident
  3709.         mov     bl,0ah                  ; 132x25
  3710. ckfnr4:    int    screen
  3711.     clc
  3712.     ret
  3713. ckevga:    mov    ax,0c000h        ; Everex FVGA-673, EV-678 rom segment
  3714.     mov    es,ax
  3715.     mov    di,76h            ; offset in rom for board's id string
  3716.     lea    si,evgid        ; id string
  3717.     mov    cx,evglen        ; length of id string
  3718.     cld
  3719.     repe    cmpsb            ; do they match?
  3720.     je    ckevg0            ; e = yes
  3721.     mov    di,9dh            ; offset in ROM for board's ID string
  3722.     lea    si,evvid        ; ID string
  3723.     mov    cx,evvlen        ; length of ID string
  3724.     cld
  3725.     repe    cmpsb            ; do they match?
  3726.     jne    ckevg2            ; ne = no
  3727. ckevg0:    mov    ax,3            ; prepare to reset video mode
  3728.     cmp    byte ptr temp,0        ; setting or resetting mode?
  3729.     je    ckevg1            ; e = resetting, exit
  3730.     mov    ax,0070h        ; mode for 132x25
  3731.     mov    bl,0ah            ; Everex mode 0ah
  3732. ckevg1:    int    screen
  3733.     clc
  3734.     ret
  3735. ckevg2:    stc                ; say board not found
  3736.     ret
  3737.                     ; AT&T EGA/VGA boards
  3738. ckatt:    mov    ax,0c000h        ; seg of first signature
  3739.     mov    es,ax
  3740.     mov    si,offset attvdc6    ; first pattern
  3741.     mov    di,35h            ; test area
  3742.     cld
  3743.     mov    cx,attvdlen        ; length
  3744.     repe    cmpsb
  3745.     je    ckatt2            ; e = found
  3746.     mov    cx,attvdlen        ; try second signature, same length
  3747.     mov    si,offset attvdc7
  3748.     mov    ax,0e000h        ; seg of second signature
  3749.     mov    es,ax
  3750.     mov    di,10h            ; test area
  3751.     repe    cmpsb
  3752.     je    ckatt2            ; e = found
  3753.     stc                ; not found
  3754.     ret
  3755. ckatt2:    mov    al,crt_norm        ; old mode
  3756.     xor    ah,ah
  3757.     cmp    byte ptr temp,0        ; resetting to 80 col?
  3758.     je    ckatt3            ; e = yes
  3759.     mov    ax,0055h        ; 132 cols, set mode 55h
  3760. ckatt3:    int    screen
  3761.     clc
  3762.     ret
  3763.                     ; IBM XGA 132 columns
  3764. ckxga:    push    bp            ; (old BIOSes are still around)
  3765.     push    ds            ; set es to data segment
  3766.     pop    es
  3767.     mov    ax,1b00h        ; get functionality table
  3768.     xor    bx,bx
  3769.     mov    di,offset dumpbuf    ; es:di is 64 bytes of workspace
  3770.     int    screen
  3771.     cmp    al,1bh            ; is this call supported?
  3772.     jne    ckxgax            ; ne = no, fail
  3773.     les    bx,dword ptr dumpbuf    ; get the address of the modes info
  3774.     test    byte ptr es:[bx+2],10h    ; is mode 14h supported?
  3775.     jz    ckxman            ; z = no, try manual method for now
  3776.     mov    ax,3            ; assume resetting to mode 3, 80x25
  3777.     cmp    byte ptr temp,0        ; setting 132 columns?
  3778.     je    ckxga1            ; e = no, resetting to 80 columns
  3779.     mov    ax,14h            ; invoke IBM XGA mode 14h, 132x25
  3780. ckxga1:    int    screen
  3781. ckxga2:    pop    bp
  3782.     clc                ; say success
  3783.     ret
  3784. ckxgax:    pop    bp
  3785.     mov    xga_reg_base,-2        ; flag saying no XGA Adapter found
  3786.     stc                ; say failure
  3787.     ret
  3788.  
  3789. ckxman:    call    dword ptr fxgaman    ; do tests/sets manually
  3790.     pop    bp
  3791.     jnc    ckxman1            ; nc = success
  3792.     mov    xga_reg_base,-2        ; flag saying no XGA Adapter found
  3793. ckxman1:ret
  3794. chgdsp    endp
  3795. code    ends
  3796.  
  3797. ; XGA mode setting via going to the hardware manually
  3798. ; Code furnished by Bert Tyler, National Institue of Health
  3799. code1    segment
  3800.     assume    cs:code1
  3801.  
  3802. xgaman    proc    FAR
  3803.     cmp    xga_reg_base,-2        ; has the XGA detector already failed?
  3804.     je    xgafail            ; e = yes, fail again
  3805.     cmp    xga_reg_base,-1        ; have we already found the XGA?
  3806.     je    xga_loc            ; e = no
  3807.     jmp    xga_do1            ; yes, process it
  3808. xga_loc:push    es
  3809.     mov    ah,35h            ; DOS get interrupt vector
  3810.     mov    al,15h            ; Int 15h
  3811.         int     dos                     ; returns vector in es:bx
  3812.     mov    ax,es            ; segment part
  3813.     pop    es
  3814.     or    ax,ax            ; undefined vector?
  3815.     jz    xgafail            ; z = yes
  3816.     mov    dx,-1            ; start with an invalid POS address
  3817.     mov    ax,0c400h        ; look for POS base address
  3818.     int    15h            ;  (Microchannel machines only)
  3819.     jc    xgafail            ; c = error, not a MC machine
  3820.     mov    word ptr dumpbuf,dx    ; save pos_base_address
  3821.     xor    cx,cx            ; check all MCA slots & motherboard
  3822.     cmp    dx,-1            ; do we have a good POS?
  3823.     jne    xga_lp1            ; ne = yes, proceed with MCA checks
  3824. xgafail:stc                ; fail
  3825.     ret
  3826.  
  3827. xga_lp1:cli                ; no interrupts, please
  3828.     cmp    cx,0            ; treat the motherboard differently?
  3829.     jne    xga_sk4            ; ne = yes
  3830.     mov    al,0dfh            ; enable the motherboard for setup
  3831.     mov    dx,94h
  3832.     out    dx,al
  3833.     jmp    short xga_sk5
  3834. xga_sk4:mov    ax,0c401h        ; enable an MCA slot for setup
  3835.     mov    bx,cx            ;  this slot
  3836.     int    15h
  3837. xga_sk5:mov    dx,word ptr dumpbuf    ; get pos record for the slot
  3838.     in    ax,dx            ;  ID
  3839.     mov    word ptr dumpbuf+2,ax
  3840.     add    dx,2            ; compute IO Res Base
  3841.     in    al,dx            ;  get POS data byte1
  3842.     and    ax,0eh            ;  muck about with it to get reg base
  3843.     shl    ax,1
  3844.     shl    ax,1
  3845.     shl    ax,1
  3846.     add    ax,2100h
  3847.     mov    xga_reg_base,ax
  3848.     cmp    cx,0            ; treat the motherboard differently?
  3849.     jne    xga_sk6            ; ne = yes
  3850.     mov    al,0ffh            ; enable the motherboard for normal
  3851.     out    094h,al
  3852.     jmp    short xga_sk7
  3853. xga_sk6:mov    ax,0c402h        ; enable the MCA slot for normal
  3854.     mov    bx,cx            ;  this slot
  3855.     int    15h
  3856. xga_sk7:sti                ; interrupts on again
  3857.  
  3858.     mov    ax,word ptr dumpbuf+2    ; is an XGA adapter on this slot?
  3859.     cmp    ax,08fd8h
  3860.     jae    xga_sk8            ; ae = yes
  3861.     jmp    xga_lp2            ; try another slot
  3862. xga_sk8:cmp    ax,08fdbh        ; still within range?
  3863.     jbe    xga_sk9            ; be = yes
  3864.     jmp    xga_lp2            ; no, try another slot
  3865. xga_sk9:mov    dx,xga_reg_base        ; is there a monitor on this slot?
  3866.     add    dx,0ah
  3867.     mov    al,052h
  3868.     out    dx,al
  3869.     mov    dx,xga_reg_base
  3870.     add    dx,0bh
  3871.     in    al,dx
  3872.     and    al,0fh
  3873.     cmp    al,0fh
  3874.     jne    xga_ska            ; ne = yes
  3875.     jmp    xga_lp2            ; no
  3876. xga_ska:mov    dx,xga_reg_base        ; is this XGA in VGA mode?
  3877.     in    al,dx
  3878.     test    al,1
  3879.     jnz    xga_do1            ; nz = yes, found it!
  3880.  
  3881. xga_lp2:inc    cx            ; try another adapter?
  3882.     cmp    cx,9            ; done all slots?
  3883.     ja    xga_no            ; a = yes
  3884.     jmp    xga_lp1            ; no, try another slot
  3885. xga_no:    jmp    xgafail            ; fail
  3886.  
  3887. ;    *finally* put the XGA into 132-column or 80-column mode
  3888.  
  3889. xga_do1:cmp    byte ptr temp,0        ; setting 80-column mode?
  3890.     jne    xga_do2            ; ne = no, 132 columns
  3891.     jmp    xga_do3            ; do 80 column mode
  3892.  
  3893.                     ; 132-column mode routine
  3894. xga_do2:mov    dx,xga_reg_base        ; (the manual doesn't explain...)
  3895.     add    dx,0ah
  3896.     mov    ax,1550h
  3897.     out    dx,ax
  3898.     mov    ax,1450h
  3899.     out    dx,ax
  3900.     mov    ax,0454h
  3901.     out    dx,ax
  3902.     mov    ax,1202h        ; select 400 scan lines
  3903.     mov    bl,30h
  3904.     int    screen
  3905.     mov    ax,0+3            ; set video mode 3
  3906.     int    screen
  3907.  
  3908.     mov    dx,xga_reg_base        ; (the manual doesn't explain...)
  3909.     add    dx,0ah
  3910.     mov    al,50h
  3911.     out    dx,al
  3912.     inc    dx
  3913.     in    al,dx
  3914.     or    al,1
  3915.     out    dx,al
  3916.  
  3917.     mov    dx,xga_reg_base        ; (the manual doesn't explain...)
  3918.     add    dx,0ah
  3919.     mov    al,50h
  3920.     out    dx,al
  3921.     inc    dx
  3922.     in    al,dx
  3923.     and    al,0fdh
  3924.     out    dx,al
  3925.  
  3926.     mov    dx,xga_reg_base        ; (the manual doesn't explain...)
  3927.     add    dx,0ah
  3928.     mov    al,50h
  3929.     out    dx,al
  3930.     inc    dx
  3931.     in    al,dx
  3932.     and    al,0fch
  3933.     out    dx,al
  3934.  
  3935.     mov    dx,xga_reg_base        ; (the manual doesn't explain...)
  3936.     mov    al,3
  3937.     out    dx,al
  3938.  
  3939.     mov    dx,xga_reg_base        ; (the manual doesn't explain...)
  3940.     add    dx,0ah
  3941.     mov    ax,0154h
  3942.     out    dx,ax
  3943.     mov    ax,8070h
  3944.     out    dx,ax
  3945.  
  3946.     mov    dx,xga_reg_base        ; (the manual doesn't explain...)
  3947.     add    dx,0ah
  3948.     mov    al,50h
  3949.     out    dx,al
  3950.     inc    dx
  3951.     in    al,dx
  3952.     and    al,0efh
  3953.     out    dx,al
  3954.  
  3955.     mov    dx,03d4h        ; (the manual doesn't explain...)
  3956.     mov    ax,11h
  3957.     out    dx,al
  3958.     inc    dx
  3959.     in    al,dx
  3960.     and    al,7fh
  3961.     out    dx,al
  3962.  
  3963.     mov    dx,03d4h        ; (the manual doesn't explain...)
  3964.     mov    ax,0
  3965.     out    dx,al
  3966.     inc    dx
  3967.     mov    ax,0a4h
  3968.     out    dx,al
  3969.  
  3970.     mov    dx,03d4h        ; (the manual doesn't explain...)
  3971.     mov    ax,1
  3972.     out    dx,al
  3973.     inc    dx
  3974.     mov    ax,83h
  3975.     out    dx,al
  3976.  
  3977.     mov    dx,03d4h        ; (the manual doesn't explain...)
  3978.     mov    ax,2
  3979.     out    dx,al
  3980.     inc    dx
  3981.     mov    ax,84h
  3982.     out    dx,al
  3983.  
  3984.     mov    dx,03d4h        ; (the manual doesn't explain...)
  3985.     mov    ax,3
  3986.     out    dx,al
  3987.     inc    dx
  3988.     mov    ax,83h
  3989.     out    dx,al
  3990.  
  3991.     mov    dx,03d4h        ; (the manual doesn't explain...)
  3992.     mov    ax,4
  3993.     out    dx,al
  3994.     inc    dx
  3995.     mov    ax,90h
  3996.     out    dx,al
  3997.  
  3998.     mov    dx,03d4h        ; (the manual doesn't explain...)
  3999.     mov    ax,5
  4000.     out    dx,al
  4001.     inc    dx
  4002.     mov    ax,80h
  4003.     out    dx,al
  4004.  
  4005.     mov    dx,xga_reg_base        ; (the manual doesn't explain...)
  4006.     add    dx,0ah
  4007.     mov    ax,0a31ah
  4008.     out    dx,ax
  4009.     mov    ax,001bh
  4010.     out    dx,ax
  4011.  
  4012.     mov    dx,03d4h        ; (the manual doesn't explain...)
  4013.     mov    ax,13h
  4014.     out    dx,al
  4015.     inc    dx
  4016.     mov    ax,42h
  4017.     out    dx,al
  4018.  
  4019.     mov    dx,03d4h        ; (the manual doesn't explain...)
  4020.     mov    al,11h
  4021.     out    dx,al
  4022.     inc    dx
  4023.     in    al,dx
  4024.     or    al,80h
  4025.     out    dx,al
  4026.  
  4027.     mov    dx,xga_reg_base        ; (the manual doesn't explain...)
  4028.     add    dx,0ah
  4029.     mov    al,50h
  4030.     out    dx,al
  4031.     inc    dx
  4032.     in    al,dx
  4033.     or    al,3
  4034.     out    dx,al
  4035.  
  4036.     mov    dx,03c4h        ; (the manual doesn't explain...)
  4037.     mov    ax,1
  4038.     out    dx,al
  4039.     inc    dx
  4040.     in    al,dx
  4041.     or    al,1
  4042.     out    dx,al
  4043.  
  4044.     mov    dx,03dah        ; (the manual doesn't explain...)
  4045.     in    al,dx
  4046.  
  4047.     mov    dx,003c0h        ; (the manual doesn't explain...)
  4048.     mov    al,13h
  4049.     out    dx,al
  4050.     xor    al,al
  4051.     out    dx,al
  4052.     mov    al,20h
  4053.     out    dx,al
  4054.  
  4055.     mov    ax,40h            ; tell the BIOS we have 132 columns
  4056.     mov    es,ax
  4057.     mov    byte ptr es:[4ah],132    ; set Bios screen width data area
  4058.     clc                ; return success
  4059.     ret
  4060.                         ; Set 80 column mode
  4061. xga_do3:mov    dx,xga_reg_base        ; (the manual doesn't explain...)
  4062.     add    dx,01h
  4063.     xor    al,al
  4064.     out    dx,al
  4065.  
  4066.     mov    dx,xga_reg_base        ; (the manual doesn't explain...)
  4067.     add    dx,4
  4068.     xor    al,al
  4069.     out    dx,al
  4070.  
  4071.     mov    dx,xga_reg_base        ; (the manual doesn't explain...)
  4072.     add    dx,5
  4073.     mov    al,0ffh
  4074.     out    dx,al
  4075.  
  4076.     mov    dx,xga_reg_base        ; (the manual doesn't explain...)
  4077.     add    dx,0ah
  4078.     mov    ax,0ff64h
  4079.     out    dx,ax
  4080.  
  4081.     mov    dx,xga_reg_base        ; (the manual doesn't explain...)
  4082.     add    dx,0ah
  4083.     mov    ax,1550h
  4084.     out    dx,ax
  4085.  
  4086.     mov    dx,xga_reg_base        ; (the manual doesn't explain...)
  4087.     add    dx,0ah
  4088.     mov    ax,1450h
  4089.     out    dx,ax
  4090.  
  4091.     mov    dx,xga_reg_base        ; (the manual doesn't explain...)
  4092.     add    dx,0ah
  4093.     mov    ax,0051h
  4094.     out    dx,ax
  4095.  
  4096.     mov    dx,xga_reg_base        ; (the manual doesn't explain...)
  4097.     add    dx,0ah
  4098.     mov    ax,0454h
  4099.     out    dx,ax
  4100.  
  4101.     mov    dx,xga_reg_base        ; (the manual doesn't explain...)
  4102.     add    dx,0ah
  4103.     mov    ax,7f70h
  4104.     out    dx,ax
  4105.  
  4106.     mov    dx,xga_reg_base        ; (the manual doesn't explain...)
  4107.     add    dx,0ah
  4108.     mov    ax,202ah
  4109.     out    dx,ax
  4110.  
  4111.     mov    dx,xga_reg_base        ; (the manual doesn't explain...)
  4112. ;;    add    dx,00h
  4113.     mov    al,1
  4114.     out    dx,al
  4115.  
  4116.     mov    dx,03c3h        ; (the manual doesn't explain...)
  4117.     mov    al,1
  4118.     out    dx,al
  4119.  
  4120.     mov    ax,1202h        ; select 400 scan lines
  4121.     mov    bl,30h
  4122.     int    screen
  4123.     mov    ax,0+3            ; set video mode 3
  4124.     int    screen
  4125.     clc                ; return success
  4126.     ret
  4127. xgaman    endp
  4128. code1    ends
  4129.  
  4130. code    segment
  4131.     assume    cs:code
  4132.  
  4133. ; Character write/read and cursor manipulation routines for terminal emulator
  4134. ; All registers other than returned values are preserved.
  4135.  
  4136. ; Read char and attributes under cursor.
  4137. ; Returns AL = character, AH = video attributes
  4138. getatch    proc    near
  4139.     push    bx
  4140.     mov    ah,8            ; read char and attributes
  4141.     xor    bh,bh            ; page 0
  4142.     int    screen            ; Bios video call
  4143.     pop    bx
  4144.     ret
  4145. getatch    endp
  4146.  
  4147. ; Read cursor position
  4148. ; DH = column, DL = row, both counted from 0,0 at upper left corner
  4149. getpos    proc    near
  4150.     push    ax
  4151.     push    bx
  4152.     mov    ah,3            ; get cursor position
  4153.     xor    bh,bh            ; page 0
  4154.     int    screen
  4155.     pop    bx
  4156.     pop    ax
  4157.     ret
  4158. getpos    endp
  4159.  
  4160. ; Set cursor postion
  4161. ; DH = column, DL = row, both counted from 0,0 at upper left corner
  4162. setpos    proc    near
  4163.     push    ax
  4164.     push    bx
  4165.     mov    ah,2            ; set cursor
  4166.     xor    bh,bh            ; page 0
  4167.     int    screen
  4168.     pop    bx
  4169.     pop    ax
  4170.     ret
  4171. setpos    endp
  4172.  
  4173. ; Write char and attribute to screen at cursor position, do not move cursor.
  4174. ; AL = char, AH = video attribute
  4175. setatch    proc    near
  4176.     push    ax
  4177.     push    bx
  4178.     push    cx
  4179.     mov    cx,1            ; one char
  4180.     mov    bl,ah            ; attribute
  4181.     xor    bh,bh            ; page 0
  4182.     mov    ah,9            ; write char, do not move cursor
  4183.     int    screen
  4184.     pop    cx
  4185.     pop    bx
  4186.     pop    ax
  4187.     ret
  4188. setatch    endp
  4189.  
  4190. ; Write char to screen at cursor position, move cursor, use current attributes
  4191. ; AL = char.
  4192. putchar proc    near
  4193.     push    ax
  4194.     push    bx
  4195.     mov    ah,0eh            ; write char, increment cursor
  4196.     xor    bh,bh            ; page 0
  4197.     int    screen
  4198.     pop    bx
  4199.     pop    ax
  4200.     ret
  4201. putchar    endp
  4202.  
  4203. ; Get bold video attribute bit
  4204. ; Enter with AH = video attribute byte, returns AH = bold attribute bit
  4205. getbold    proc    near
  4206.     and    ah,att_intensity    ; select bold bit
  4207.     xor    ah,userbold        ; invert with user bold
  4208.     ret
  4209. getbold endp
  4210.  
  4211. ; Set bold video attribute bit
  4212. ; Enter with AH = video attribute byte
  4213. setbold proc    near
  4214.     or    ah,att_intensity    ; set bold bit
  4215.     xor    ah,userbold        ; invert with user bold
  4216.     ret
  4217. setbold endp
  4218.  
  4219. ; Clear bold video attribute bit
  4220. ; Enter with AH = video attribute byte, returns new attribute byte in AH
  4221. clrbold    proc    near
  4222.     and    ah,not att_intensity    ; clear bold bit
  4223.     or    ah,userbold        ; invert with user bold
  4224.     ret
  4225. clrbold    endp
  4226.  
  4227. ; Get blink video attribute bit
  4228. ; Enter with AH = video attribute byte, returns AH = blink attribute bit
  4229. getblink proc    near
  4230.     and    ah,att_blink        ; get blink bit
  4231.     ret
  4232. getblink endp
  4233.  
  4234. ; Set blink video attribute bit
  4235. ; Enter with AH = video attribute byte
  4236. setblink proc    near
  4237.     or    ah,att_blink        ; set blink bit
  4238.     ret
  4239. setblink endp
  4240.  
  4241. ; Clear blink video attribute bit
  4242. ; Enter with AH = video attribute byte, returns new attribute byte in AH
  4243. clrblink proc    near
  4244.     and    ah,not att_blink    ; clear blink bit
  4245.     ret
  4246. clrblink endp
  4247.  
  4248. ; Get underline video attribute bit
  4249. ; Enter with AH = video attribute byte, returns AH = underline attribute bit
  4250. getunder proc    near
  4251.     ret
  4252. getunder endp
  4253.  
  4254. ; Set underline video attribute bit
  4255. ; Enter with AH = video attribute byte, video_state (0=normal)
  4256. ; Return AH holding new attribute byte, new video_state.
  4257. setunder proc    near
  4258.     cmp    crt_mode,7        ; monochrome display adapter mode?
  4259.     je    setund2            ; e = yes, otherwise reverse video
  4260.     jmp    setrev
  4261. setund2:call    brkatt            ; break apart attributes
  4262.     or    al,att_underline    ; set underline bit
  4263.     call    addatt            ; reassemble attributes
  4264.     ret
  4265. setunder endp
  4266.  
  4267. ; Clear underline video attribute bit
  4268. ; Enter with AH = video attribute byte, returns new attribute byte in AH and
  4269. ; new video_state.
  4270. clrunder proc    near
  4271.     cmp    crt_mode,7        ; monochrome display adapter mode?
  4272.     je    clrund2            ; e = yes, otherwise reverse video
  4273.     jmp    clrrev
  4274. clrund2:call    brkatt            ; break apart attributes
  4275.     and    al,not att_underline    ; turn off underline bit
  4276.     call    addatt            ; reassemble attributes
  4277.     ret
  4278. clrunder endp
  4279.  
  4280. setrev    proc    near
  4281.     cmp    video_state,0        ; normal video
  4282.     jne    setrev1            ; ne = no, reversed already
  4283.     call    revideo            ; do reversal
  4284.     mov    video_state,1        ; say reversed
  4285. setrev1:ret
  4286. setrev    endp
  4287.  
  4288. clrrev    proc    near
  4289.     cmp    video_state,0        ; normal video?
  4290.     je    clrrev1            ; e = yes
  4291.     call    revideo            ; do reversal
  4292.     mov    video_state,0        ; say normal
  4293. clrrev1:ret
  4294. clrrev    endp
  4295.  
  4296.  
  4297. ; Compute reversed video attribute byte. Normally preserves blink/bold.
  4298. ; Enter with AH = video attribute byte, returns new attribute byte in AH
  4299. revideo    proc    near
  4300.     call    brkatt            ; separate colors from blink/bold
  4301.     rol    ah,1            ; reverse foreground & background
  4302.     rol    ah,1            ; RGB bits
  4303.     rol    ah,1
  4304.     rol    ah,1
  4305.     call    addatt            ; reinsert bold/blink bits
  4306.     ret
  4307. revideo    endp
  4308.  
  4309. ; This routine picks an attribute apart into its component "parts" - the
  4310. ; base attribute for the screen and the "extras" - i.e., blink, intensity
  4311. ; and underline.
  4312. ; enter with    ah = a cursor attribute
  4313. ; return    ah = base attribute for screen (07H normal, 70H reverse).
  4314. ;        al = "extra" attributes
  4315. ; Note that there is a complementary routine, addatt, for putting attributes
  4316. ; back together.
  4317.  
  4318. brkatt: xor    al,al            ; Clear returned "extra" attributes
  4319.     test    ah,att_intensity    ; intensity attribute on?
  4320.     jz    brkat3            ; z = no, check blink
  4321.     or    al,att_intensity    ; set intensity
  4322. brkat3: test    ah,att_blink        ; blink on?
  4323.     jz    brkat4            ; z = no
  4324.     or    al,att_blink        ; set blink
  4325. brkat4:    and    ah,not(att_intensity+att_blink)    ;strip blink/bold, leave color
  4326.     cmp    crt_mode,7        ; monochrome display adapter mode?
  4327.     jne    brkat2            ; ne = no, cut this short for color
  4328.     test    ah,att_low_mask        ; are any of these on?
  4329.     jnz    brkat1            ; nz = yes, can't be underline
  4330.     test    ah,att_underline    ; underline?
  4331.     jz    brkat2            ; z = no, some kind of reverse video
  4332.     or    al,att_underline    ; say underline
  4333.     test    ah,70h ;;att_reverse    ; reverse video + underline?
  4334.     jz    brkat1            ; z = no, fix up low nibble
  4335.     and    ah,not att_underline    ; clear the underline bit in ah
  4336.     ret
  4337. brkat1: or    ah,att_normal        ; normal, turn on all normal bits
  4338. brkat2:    ret
  4339.  
  4340. ; This routine builds a cursor attribute given the base attribute for the
  4341. ; screen background and the "extra" attributes we want (blink, etc.).
  4342. ; enter with    ah = base attribute for background (07H or 70H)
  4343. ;        al = "extra" attributes (89H for all three)
  4344. ; return    ah = base combined with "extras".
  4345.  
  4346. addatt: test    al,att_underline    ; want underline?
  4347.     jz    addat1            ; z = no, no need for hack
  4348.     and    ah,not att_low_mask    ; clear background colors
  4349. addat1: or    ah,al            ; Or in the attributes
  4350.     ret
  4351.  
  4352.  
  4353. ; This routine is called when we want to reverse everything on the screen
  4354. ; from normal to reverse video, or vice versa.    It is called only when
  4355. ; the decscnm attribute is changed.
  4356. ; Call:        no arguments.
  4357.  
  4358. revscn    proc    near
  4359.     push    ax
  4360.     push    bx
  4361.     push    cx
  4362.     push    dx
  4363.     mov    dh,byte ptr low_rgt+1    ; Compute last screen offset in ax
  4364.     inc    dh            ; One more row to catch mode line
  4365.     mov    dl,crt_cols        ; physical width
  4366.     dec    dl            ; and we count from 0
  4367.     call    scrloc            ; get screen offset into ax
  4368.     mov    cx,ax            ; Save it in cx for a minute
  4369.     add    cx,2
  4370.     sar    cx,1            ; In 16-bit words please
  4371.     push    di            ; Save some more acs
  4372.     push    es
  4373.     push    cx            ; save word count for Topview
  4374.     mov    ax,tv_segs        ; Get address of screen in ax, es:di
  4375.     mov    es,ax
  4376.     xor    di,di
  4377.     call    scroff            ; Turn screen off if color card
  4378.     cld
  4379. revsc1: mov    ax,es:[di]        ; Fetch a word
  4380.     mov    bl,al            ; Save the character
  4381.     call    revideo            ; get reversed video attributes (AH)
  4382.     call    addatt            ; Put attributes back together
  4383.     mov    al,bl            ; Restore character
  4384.     stosw                ; Stuff into screen memory
  4385.     loop    revsc1            ; Loop for entire screen
  4386.     pop    cx            ; recover word count for Topview
  4387.     call    scrsync            ; synch with Topview
  4388.     call    scron            ; Turn screen back on if color card
  4389.     pop    es            ; Restore segment register
  4390.     pop    di            ; And destination index
  4391.     pop    dx
  4392.     pop    cx
  4393.     pop    bx
  4394.     pop    ax
  4395.     ret
  4396. revscn    endp
  4397.  
  4398. ; IBM PC worker for insert/delete cx characters at and including cursor.
  4399. ; dh= logical cursor row, dl= logical cursor column,
  4400. ; cx has character repeat count, bl = logical screen width-1,
  4401. ; bh = +1 for insert, -1 for delete chars.
  4402. ; Double width lines have cx and dl doubled by our caller. Writing right to
  4403. ; left is managed here.
  4404. insdecom proc    near
  4405.     push    es
  4406.     push    ax
  4407.     push    cx
  4408.     push    dx
  4409.     push    si
  4410.     push    di
  4411.     mov    temp,0            ; worker temp
  4412.     mov    skip,cx            ; number of chars to insert/delete
  4413.     call    scrseg            ; pick up screen segment in es:di,ax
  4414.            test    vtemu.vtflgop,vswdir    ; writing left to right?
  4415.     jz    insdec1            ; z = yes, no changes needed
  4416.     sub    dl,bl            ; logical to physical cursor position
  4417.     neg    dl            ; make dl positive again
  4418.     xor    bl,bl            ; right-to-left, edge is left margin
  4419.                     ; bl is now logical eol
  4420. insdec1:mov    cl,dl            ; physical cursor dl saved here
  4421.     or    bh,bh            ; insert?
  4422.     jl    insdec2            ; l = no, leave dl at cursor column
  4423.     mov    dl,bl            ; insert uses logical end of line
  4424. insdec2:call    scrloc            ; ax = offset in regen buffer
  4425.     add    di,ax            ; es:di = destination so far
  4426.     mov    si,di            ; align source to be same place
  4427.     or    bh,bh            ; inserting?
  4428.     jge    insdec4            ; ge = yes
  4429.     test    vtemu.vtflgop,vswdir    ; writing right to left?
  4430.     jnz    insdec4a        ; nz = yes
  4431. insdec3:add    si,skip            ; delete
  4432.     add    si,skip
  4433.     mov    byte ptr temp+1,0    ; remember direction here as 0=cld
  4434.     cld
  4435.     jmp    short insdec5
  4436. insdec4:test    vtemu.vtflgop,vswdir    ; insert, writing right to left?
  4437.     jnz    insdec3            ; nz = yes
  4438. insdec4a:sub    si,skip
  4439.     sub    si,skip
  4440.     mov    byte ptr temp+1,0    ; remember direction here as 1=std
  4441.     std
  4442.  
  4443. insdec5:call    scroff            ; video off
  4444.     xor    ch,ch
  4445.     sub    cl,bl            ; cursor - margin
  4446.     jnc    insdec6            ; nc = non-negative
  4447.     neg    cl            ; make positive
  4448. insdec6:inc    cx            ; include cursor location too
  4449.     sub    cx,skip            ; cx = number chars to be moved
  4450.     jle    insdec7            ; le = none, just write spaces
  4451.     mov    byte ptr temp,cl    ; number of chars modified
  4452.     push    ds
  4453.     push    es
  4454.     pop    ds
  4455.     rep    movsw            ; mov cx chars from es:[si] to es:[di]
  4456.     pop    ds
  4457. insdec7:mov    cx,skip            ; number chars skipped
  4458.     jcxz    insdec8            ; z = none
  4459.     add    byte ptr temp,cl    ; number chars modified
  4460.     mov    al,' '            ; get fill pattern
  4461.     mov    ah,scbattr        ; attribute
  4462.     rep    stosw            ; fill at the end
  4463. insdec8:cld                ; restore direction flag
  4464.     call    scron            ; video back on for CGA screens
  4465.     mov    cl,byte ptr temp    ; number of char cells touched
  4466.     xor    ch,ch
  4467.     cmp    byte ptr temp+1,0    ; was Direction bit set?
  4468.     je    insdec9            ; e = no
  4469.     add    di,cx            ; make di be its highest value
  4470. insdec9:call    scrsync            ; synch Topview
  4471.     pop    di
  4472.     pop    si
  4473.     pop    dx
  4474.     pop    cx
  4475.     pop    ax
  4476.     pop    es
  4477.     ret
  4478. insdecom endp
  4479.  
  4480. ; Set coloring attributes.
  4481. ; Enter with AH holding current video attribute byte,
  4482. ; BL holding ANSI color code (30-37 or 40-47) where 30's are foreground,
  4483. ; 40's are background. ANSI colors are 1 = red, 2 = green, 4 = blue.
  4484. ; Return new attribute byte in AH.
  4485.  
  4486. setcolor proc    near
  4487.     cmp    video_state,0        ; normal video currently?
  4488.     je    setcol0            ; e = yes
  4489.     mov    al,ah            ; make a copy
  4490.     and    ax,7788h        ; strip bold,blink, keep both in al
  4491.     rol    ah,1            ; get colors in right parts
  4492.     rol    ah,1            ;  of ah = back, al = foreground
  4493.     rol    ah,1
  4494.     rol    ah,1
  4495.     call    setcol0            ; set fore or background color
  4496.     rol    ah,1            ; reverse coloring again
  4497.     rol    ah,1
  4498.     rol    ah,1
  4499.     rol    ah,1
  4500.     or    ah,al            ; put back blink and bold
  4501.     ret
  4502.  
  4503. setcol0:cmp    bl,30            ; ANSI color series?
  4504.     jb    setcol7            ; b = no
  4505.     cmp    bl,37            ; foreground set (30-37)?
  4506.     ja    setcol4            ; a = no, try background set
  4507.     sub    bl,30            ; take away the bias
  4508.     and    ah,not 07H        ; clear foreground bits
  4509.     test    bl,1            ; ANSI red?
  4510.     jz    setcol1            ; z = no
  4511.     or    ah,4            ; IBM red foreground bit
  4512. setcol1:test    bl,2            ; ANSI & IBM green?
  4513.     jz    setcol2            ; z = no
  4514.     or    ah,2            ; IBM green foreground bit
  4515. setcol2:test    bl,4            ; ANSI blue?
  4516.     jz    setcol3            ; z = no
  4517.     or    ah,1            ; IBM blue foreground bit
  4518. setcol3:ret
  4519.  
  4520. setcol4:cmp    bl,40            ; background color set?
  4521.     jb    setcol7            ; b = no
  4522.     cmp    bl,47            ; background set is 40-47
  4523.     ja    setcol7            ; nb = no, not a color command
  4524.     sub    bl,40            ; take away the bias
  4525.     and    ah,not 70H        ; clear background bits
  4526.     test    bl,1            ; ANSI red?
  4527.     jz    setcol5            ; z = no
  4528.     or    ah,40h            ; IBM red background bit
  4529. setcol5:test    bl,2            ; ANSI & IBM green?
  4530.     jz    setcol6            ; z = no
  4531.     or    ah,20h            ; IBM green background bit
  4532. setcol6:test    bl,4            ; ANSI blue?
  4533.     jz    setcol7            ; z = no
  4534.     or    ah,10h            ; IBM blue background bit
  4535. setcol7:ret
  4536. setcolor endp
  4537.  
  4538. ; Routine to do keyclick if flag is set, no arguments
  4539. vclick    proc    near
  4540.     test    vtemu.vtflgop,vskeyclick ; is keyclick flag on?
  4541.     jz    vclick1            ; z = no, just return
  4542.     push    bx
  4543.     push    di
  4544.     mov    di,500            ; 500 Hertz
  4545.     mov    bx,1            ; For 1 millisecond
  4546.     call    vtsound            ; Do it
  4547.     pop    di            ; Restore the ACs
  4548.     pop    bx
  4549. vclick1:ret
  4550. vclick    endp
  4551.  
  4552. ; Routine to do VT100-style bell, no arguments
  4553. vtbell    proc    near
  4554.     cmp    belltype,1        ; visual bell?
  4555.     je    vtbell1            ; e = yes
  4556.     ja    vtbell2            ; a = no bell
  4557.     push    di            ; audible bell
  4558.     push    bx
  4559.     mov    di,880            ; 880 Hertz
  4560.     mov    bx,40            ; For 40 ms
  4561.     call    vtsound            ; Do it
  4562.     pop    bx
  4563.     pop    di
  4564.     ret
  4565. vtbell1:call    revscn            ; reverse screen
  4566.     push    ax
  4567.     mov    ax,40            ; for 40 milliseconds
  4568.     call    pcwait
  4569.     pop    ax
  4570.     call    revscn            ; put back
  4571. vtbell2:ret
  4572. vtbell    endp
  4573.  
  4574. ; Routine to make noise of arbitrary frequency for arbitrary duration.
  4575. ; Similar to routine (with typo removed) in "IBM PC Assembly Language:
  4576. ; A Guide for Programmers", Leo J. Scanlon, 1983 Robert J. Brady Co.,
  4577. ; Bowie, MD., page 270. Modified by J R Doupnik to use 0.1 millsec interval.
  4578. ; Call:        di/    frequency in Hertz.
  4579. ;        bx/    duration in 1 millisecond units
  4580. vtsound proc    near
  4581.     push    ax            ; save regs
  4582.     push    cx
  4583.     push    dx
  4584.     mov    al,0B6H            ; write timer mode register
  4585.     out    43H,al
  4586.     mov    dx,14H            ; timer divisor is
  4587.     mov    ax,4F38H        ; 1331000/frequency
  4588.     div    di
  4589.     out    42H,al            ; write timer 2 count low byte
  4590.     mov    al,ah
  4591.     out    42H,al            ; write timer 2 count high byte
  4592.     in    al,61H            ; get current port B setting
  4593.     or    al,3            ; turn speaker on
  4594.     out    61H,al
  4595.     mov    ax,bx            ; number of milliseconds to wait
  4596.     call    pcwait            ; do the calibrated wait
  4597.     in    al,61H            ; get current port B setting
  4598.     and    al,0fch            ; turn off speaker and timer
  4599.     out    61H,al
  4600.     pop    dx            ; restore regs
  4601.     pop    cx
  4602.     pop    ax
  4603.     ret
  4604. vtsound endp
  4605. code    ends
  4606.     end
  4607.